Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(295)

Side by Side Diff: gpu/gles2_conform_support/egl/display.cc

Issue 1714883002: command_buffer_gles2: Implement EGL default Display as a global object (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@command_buffer_gles2-multiple-contexts
Patch Set: add nogncheck to egl_native_windowless.cc Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/gles2_conform_support/egl/display.h" 5 #include "gpu/gles2_conform_support/egl/display.h"
6 6
7 #include <stddef.h> 7 #include "gpu/gles2_conform_support/egl/config.h"
8 #include <stdint.h> 8 #include "gpu/gles2_conform_support/egl/context.h"
9 #include "gpu/gles2_conform_support/egl/surface.h"
10 #include "gpu/gles2_conform_support/egl/thread_state.h"
9 11
10 #include <vector> 12 namespace egl {
11 #include "base/at_exit.h"
12 #include "base/bind.h"
13 #include "base/bind_helpers.h"
14 #include "base/lazy_instance.h"
15 #include "gpu/command_buffer/client/gles2_implementation.h"
16 #include "gpu/command_buffer/client/gles2_lib.h"
17 #include "gpu/command_buffer/client/transfer_buffer.h"
18 #include "gpu/command_buffer/common/value_state.h"
19 #include "gpu/command_buffer/service/context_group.h"
20 #include "gpu/command_buffer/service/mailbox_manager.h"
21 #include "gpu/command_buffer/service/memory_tracking.h"
22 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
23 #include "gpu/command_buffer/service/valuebuffer_manager.h"
24 #include "gpu/gles2_conform_support/egl/config.h"
25 #include "gpu/gles2_conform_support/egl/surface.h"
26 #include "gpu/gles2_conform_support/egl/test_support.h"
27 13
28 namespace { 14 Display::Display()
29 const int32_t kCommandBufferSize = 1024 * 1024; 15 : is_initialized_(false),
30 const int32_t kTransferBufferSize = 512 * 1024; 16 next_create_window_surface_creates_pbuffer_(false),
17 window_surface_pbuffer_width_(0),
18 window_surface_pbuffer_height_(0) {}
19
20 Display::~Display() {
21 surfaces_.clear();
22 contexts_.clear();
23 }
24 void Display::SetNextCreateWindowSurfaceCreatesPBuffer(EGLint width,
25 EGLint height) {
26 next_create_window_surface_creates_pbuffer_ = true;
27 window_surface_pbuffer_width_ = width;
28 window_surface_pbuffer_height_ = height;
31 } 29 }
32 30
33 namespace egl { 31 EGLBoolean Display::Initialize(ThreadState* ts, EGLint* major, EGLint* minor) {
34 #if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY) 32 base::AutoLock auto_lock(lock_);
35 // egl::Display is used for comformance tests and command_buffer_gles. We only 33 is_initialized_ = true;
36 // need the exit manager for the command_buffer_gles library. 34
37 // TODO(hendrikw): Find a cleaner solution for this. 35 if (major)
38 namespace { 36 *major = 1;
39 base::LazyInstance<base::Lock>::Leaky g_exit_manager_lock; 37 if (minor)
40 int g_exit_manager_use_count; 38 *minor = 4;
41 base::AtExitManager* g_exit_manager; 39 return ts->ReturnSuccess(EGL_TRUE);
42 void RefAtExitManager() {
43 base::AutoLock lock(g_exit_manager_lock.Get());
44 #if defined(COMPONENT_BUILD)
45 if (g_command_buffer_gles_has_atexit_manager) {
46 return;
47 }
48 #endif
49 if (g_exit_manager_use_count == 0) {
50 g_exit_manager = new base::AtExitManager;
51 }
52 ++g_exit_manager_use_count;
53 } 40 }
54 void ReleaseAtExitManager() { 41
55 base::AutoLock lock(g_exit_manager_lock.Get()); 42 EGLBoolean Display::Terminate(ThreadState* ts) {
56 #if defined(COMPONENT_BUILD) 43 base::AutoLock auto_lock(lock_);
57 if (g_command_buffer_gles_has_atexit_manager) { 44 is_initialized_ = false;
58 return; 45 surfaces_.clear();
59 } 46 for (const auto& context : contexts_)
60 #endif 47 context->MarkDestroyed();
61 --g_exit_manager_use_count; 48 contexts_.clear();
62 if (g_exit_manager_use_count == 0) { 49 return ts->ReturnSuccess(EGL_TRUE);
63 delete g_exit_manager; 50 }
64 g_exit_manager = nullptr; 51
52 const char* Display::QueryString(ThreadState* ts, EGLint name) {
53 base::AutoLock auto_lock(lock_);
54 if (!is_initialized_)
55 return ts->ReturnError<const char*>(EGL_NOT_INITIALIZED, nullptr);
56 switch (name) {
57 case EGL_CLIENT_APIS:
58 return ts->ReturnSuccess("OpenGL_ES");
59 case EGL_EXTENSIONS:
60 return ts->ReturnSuccess("");
61 case EGL_VENDOR:
62 return ts->ReturnSuccess("Google Inc.");
63 case EGL_VERSION:
64 return ts->ReturnSuccess("1.4");
65 default:
66 return ts->ReturnError<const char*>(EGL_BAD_PARAMETER, nullptr);
65 } 67 }
66 } 68 }
67 }
68 #endif
69 69
70 Display::Display(EGLNativeDisplayType display_id) 70 EGLBoolean Display::ChooseConfig(ThreadState* ts,
71 : display_id_(display_id), 71 const EGLint* attrib_list,
72 is_initialized_(false), 72 EGLConfig* configs,
73 create_offscreen_(false), 73 EGLint config_size,
74 create_offscreen_width_(0), 74 EGLint* num_config) {
75 create_offscreen_height_(0), 75 base::AutoLock auto_lock(lock_);
76 next_fence_sync_release_(1) { 76 if (!is_initialized_)
77 #if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY) 77 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
78 RefAtExitManager(); 78 if (num_config == nullptr)
79 #endif 79 return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
80 if (!Config::ValidateAttributeList(attrib_list))
81 return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
82 InitializeConfigsIfNeeded();
83 if (!configs)
84 config_size = 0;
85 *num_config = 0;
86 for (size_t i = 0; i < arraysize(configs_); ++i) {
87 if (configs_[i]->Matches(attrib_list)) {
88 if (*num_config < config_size) {
89 configs[*num_config] = configs_[i].get();
90 }
91 ++*num_config;
92 }
93 }
94 return ts->ReturnSuccess(EGL_TRUE);
80 } 95 }
81 96
82 Display::~Display() { 97 EGLBoolean Display::GetConfigs(ThreadState* ts,
83 gles2::Terminate(); 98 EGLConfig* configs,
84 #if defined(COMMAND_BUFFER_GLES_LIB_SUPPORT_ONLY) 99 EGLint config_size,
85 ReleaseAtExitManager(); 100 EGLint* num_config) {
86 #endif 101 base::AutoLock auto_lock(lock_);
87 } 102 if (!is_initialized_)
88 103 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
89 bool Display::Initialize() { 104 if (num_config == nullptr)
90 gles2::Initialize(); 105 return ts->ReturnError(EGL_BAD_PARAMETER, EGL_FALSE);
91 is_initialized_ = true; 106 InitializeConfigsIfNeeded();
92 return true; 107 if (!configs)
93 } 108 config_size = 0;
94 109 *num_config = arraysize(configs_);
95 bool Display::IsValidConfig(EGLConfig config) { 110 size_t count =
96 return (config != NULL) && (config == config_.get()); 111 std::min(arraysize(configs_), static_cast<size_t>(config_size));
97 } 112 for (size_t i = 0; i < count; ++i)
98 113 configs[i] = configs_[i].get();
99 bool Display::ChooseConfigs(EGLConfig* configs, 114 return ts->ReturnSuccess(EGL_TRUE);
100 EGLint config_size,
101 EGLint* num_config) {
102 // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
103 // does not support finding or choosing configs.
104 *num_config = 1;
105 if (configs != NULL) {
106 if (config_ == NULL) {
107 config_.reset(new Config);
108 }
109 configs[0] = config_.get();
110 }
111 return true;
112 }
113
114 bool Display::GetConfigs(EGLConfig* configs,
115 EGLint config_size,
116 EGLint* num_config) {
117 // TODO(alokp): Find out a way to find all configs. CommandBuffer currently
118 // does not support finding or choosing configs.
119 *num_config = 1;
120 if (configs != NULL) {
121 if (config_ == NULL) {
122 config_.reset(new Config);
123 }
124 configs[0] = config_.get();
125 }
126 return true;
127 }
128
129 bool Display::GetConfigAttrib(EGLConfig config,
130 EGLint attribute,
131 EGLint* value) {
132 const egl::Config* cfg = static_cast<egl::Config*>(config);
133 return cfg->GetAttrib(attribute, value);
134 } 115 }
135 116
136 bool Display::IsValidNativeWindow(EGLNativeWindowType win) { 117 bool Display::IsValidNativeWindow(EGLNativeWindowType win) {
137 #if defined OS_WIN 118 #if defined OS_WIN
138 return ::IsWindow(win) != FALSE; 119 return ::IsWindow(win) != FALSE;
139 #else 120 #else
140 // TODO(alokp): Validate window handle. 121 // TODO(alokp): Validate window handle.
141 return true; 122 return true;
142 #endif // OS_WIN 123 #endif // OS_WIN
143 } 124 }
144 125
145 bool Display::IsValidSurface(EGLSurface surface) { 126 EGLBoolean Display::GetConfigAttrib(ThreadState* ts,
146 return (surface != NULL) && (surface == surface_.get()); 127 EGLConfig cfg,
147 } 128 EGLint attribute,
148 129 EGLint* value) {
149 EGLSurface Display::CreateWindowSurface(EGLConfig config, 130 base::AutoLock auto_lock(lock_);
131 if (!is_initialized_)
132 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
133 const egl::Config* config = GetConfig(cfg);
134 if (!config)
135 return ts->ReturnError(EGL_BAD_CONFIG, EGL_FALSE);
136 if (!config->GetAttrib(attribute, value))
137 return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_FALSE);
138 return ts->ReturnSuccess(EGL_TRUE);
139 }
140
141 EGLSurface Display::CreatePbufferSurface(ThreadState* ts,
142 EGLConfig cfg,
143 const EGLint* attrib_list) {
144 base::AutoLock auto_lock(lock_);
145 if (!is_initialized_)
146 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
147 const egl::Config* config = GetConfig(cfg);
148 if (!config)
149 return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
150 EGLint value = EGL_NONE;
151 config->GetAttrib(EGL_SURFACE_TYPE, &value);
152 if ((value & EGL_PBUFFER_BIT) == 0)
153 return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_SURFACE);
154 if (!egl::Surface::ValidatePbufferAttributeList(attrib_list))
155 return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
156
157 int width = 1;
158 int height = 1;
159 if (attrib_list) {
160 for (const int32_t* attr = attrib_list; attr[0] != EGL_NONE; attr += 2) {
161 switch (attr[0]) {
162 case EGL_WIDTH:
163 width = attr[1];
164 break;
165 case EGL_HEIGHT:
166 height = attr[1];
167 break;
168 }
169 }
170 }
171 return DoCreatePbufferSurface(ts, width, height);
172 }
173
174 EGLSurface Display::DoCreatePbufferSurface(ThreadState* ts,
175 EGLint width,
176 EGLint height) {
177 lock_.AssertAcquired();
178 scoped_refptr<gfx::GLSurface> gl_surface;
179 gl_surface =
180 gfx::GLSurface::CreateOffscreenGLSurface(gfx::Size(width, height));
181 if (!gl_surface)
182 return ts->ReturnError(EGL_BAD_ALLOC, nullptr);
183 surfaces_.emplace_back(new Surface(gl_surface.get()));
184 return ts->ReturnSuccess<EGLSurface>(surfaces_.back().get());
185 }
186
187 EGLSurface Display::CreateWindowSurface(ThreadState* ts,
188 EGLConfig cfg,
150 EGLNativeWindowType win, 189 EGLNativeWindowType win,
151 const EGLint* attrib_list) { 190 const EGLint* attrib_list) {
152 if (surface_ != NULL) { 191 base::AutoLock auto_lock(lock_);
153 // We do not support more than one window surface. 192 if (!is_initialized_)
154 return EGL_NO_SURFACE; 193 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_SURFACE);
155 } 194 const egl::Config* config = GetConfig(cfg);
156 195 if (!config)
157 { 196 return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
158 gpu::TransferBufferManager* manager = 197 EGLint value = EGL_NONE;
159 new gpu::TransferBufferManager(nullptr); 198 config->GetAttrib(EGL_SURFACE_TYPE, &value);
160 transfer_buffer_manager_ = manager; 199 if ((value & EGL_WINDOW_BIT) == 0)
161 manager->Initialize(); 200 return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
162 } 201 if (!next_create_window_surface_creates_pbuffer_ && !IsValidNativeWindow(win))
163 scoped_ptr<gpu::CommandBufferService> command_buffer( 202 return ts->ReturnError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
164 new gpu::CommandBufferService(transfer_buffer_manager_.get())); 203 if (!Surface::ValidateWindowAttributeList(attrib_list))
165 if (!command_buffer->Initialize()) 204 return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
166 return NULL; 205 if (next_create_window_surface_creates_pbuffer_) {
167 206 next_create_window_surface_creates_pbuffer_ = false;
168 scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup( 207 window_surface_pbuffer_width_ = 0;
169 gpu_preferences_, NULL, NULL, 208 window_surface_pbuffer_height_ = 0;
170 new gpu::gles2::ShaderTranslatorCache(gpu_preferences_), 209 return DoCreatePbufferSurface(ts, window_surface_pbuffer_width_,
171 new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true)); 210 window_surface_pbuffer_height_);
172 211 }
173 decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get())); 212 scoped_refptr<gfx::GLSurface> gl_surface;
174 if (!decoder_.get()) 213 gl_surface = gfx::GLSurface::CreateViewGLSurface(win);
175 return EGL_NO_SURFACE; 214 if (!gl_surface)
176 215 return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_SURFACE);
177 executor_.reset( 216 surfaces_.emplace_back(new Surface(gl_surface.get()));
178 new gpu::CommandExecutor(command_buffer.get(), decoder_.get(), NULL)); 217 return ts->ReturnSuccess(surfaces_.back().get());
179 218 }
180 decoder_->set_engine(executor_.get()); 219
181 gfx::Size size(create_offscreen_width_, create_offscreen_height_); 220 EGLBoolean Display::DestroySurface(ThreadState* ts, EGLSurface sfe) {
182 if (create_offscreen_) { 221 base::AutoLock auto_lock(lock_);
183 gl_surface_ = gfx::GLSurface::CreateOffscreenGLSurface(size); 222 if (!is_initialized_)
184 create_offscreen_ = false; 223 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
185 create_offscreen_width_ = 0; 224 auto it = std::find(surfaces_.begin(), surfaces_.end(), sfe);
186 create_offscreen_height_ = 0; 225 if (it == surfaces_.end())
187 } else { 226 return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
188 gl_surface_ = gfx::GLSurface::CreateViewGLSurface(win); 227 surfaces_.erase(it);
189 } 228 return ts->ReturnSuccess(EGL_TRUE);
190 if (!gl_surface_.get()) 229 }
191 return EGL_NO_SURFACE; 230
192 231 EGLBoolean Display::ReleaseCurrent(ThreadState* ts) {
193 gl_context_ = gfx::GLContext::CreateGLContext(NULL, 232 base::AutoLock auto_lock(lock_);
194 gl_surface_.get(), 233 if (!is_initialized_)
195 gfx::PreferDiscreteGpu); 234 return ts->ReturnSuccess(EGL_TRUE);
196 if (!gl_context_.get()) 235 ThreadState::AutoCurrentContextRestore accr(ts);
197 return EGL_NO_SURFACE; 236 if (ts->current_context()) {
198 237 Context::MakeCurrent(ts->current_context(),
199 gl_context_->MakeCurrent(gl_surface_.get()); 238 ts->current_surface()->gl_surface(), nullptr, nullptr);
200 239 accr.SetCurrent(nullptr, nullptr);
201 EGLint depth_size = 0; 240 }
202 EGLint alpha_size = 0; 241 return ts->ReturnSuccess(EGL_TRUE);
203 EGLint stencil_size = 0; 242 }
204 GetConfigAttrib(config, EGL_DEPTH_SIZE, &depth_size); 243
205 GetConfigAttrib(config, EGL_ALPHA_SIZE, &alpha_size); 244 EGLBoolean Display::MakeCurrent(ThreadState* ts,
206 GetConfigAttrib(config, EGL_STENCIL_SIZE, &stencil_size); 245 EGLSurface draw,
207 std::vector<int32_t> attribs; 246 EGLSurface read,
208 attribs.push_back(EGL_DEPTH_SIZE); 247 EGLSurface ctx) {
209 attribs.push_back(depth_size); 248 base::AutoLock auto_lock(lock_);
210 attribs.push_back(EGL_ALPHA_SIZE); 249 if (!is_initialized_)
211 attribs.push_back(alpha_size); 250 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
212 attribs.push_back(EGL_STENCIL_SIZE); 251 ThreadState::AutoCurrentContextRestore accr(ts);
213 attribs.push_back(stencil_size); 252 // Client might have called use because it changed some other gl binding
214 // TODO(gman): Insert attrib_list. Although ES 1.1 says it must be null 253 // global state. For example, the client might have called eglMakeCurrent on
215 attribs.push_back(EGL_NONE); 254 // the same EGL as what command buffer uses. The client probably knows that
216 255 // this invalidates the internal state of command buffer, too. So reset the
217 if (!decoder_->Initialize(gl_surface_.get(), 256 // current context with accr in any case, regardless whether context or
218 gl_context_.get(), 257 // surface pointer changes.
219 gl_surface_->IsOffscreen(), 258 Surface* new_surface = GetSurface(draw);
220 size, 259 if (!new_surface)
221 gpu::gles2::DisallowedFeatures(), 260 return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
222 attribs)) { 261 new_surface = GetSurface(read);
223 return EGL_NO_SURFACE; 262 if (!new_surface)
224 } 263 return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
225 264 egl::Context* new_context = GetContext(ctx);
226 command_buffer->SetPutOffsetChangeCallback(base::Bind( 265 if (!new_context)
227 &gpu::CommandExecutor::PutChanged, base::Unretained(executor_.get()))); 266 return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
228 command_buffer->SetGetBufferChangeCallback(base::Bind( 267 if (draw != read)
229 &gpu::CommandExecutor::SetGetBuffer, base::Unretained(executor_.get()))); 268 return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
230 269
231 scoped_ptr<gpu::gles2::GLES2CmdHelper> cmd_helper( 270 Surface* current_surface = ts->current_surface();
232 new gpu::gles2::GLES2CmdHelper(command_buffer.get())); 271 Context* current_context = ts->current_context();
233 if (!cmd_helper->Initialize(kCommandBufferSize)) 272
234 return NULL; 273 if (current_context != new_context &&
235 274 new_context->is_current_in_some_thread())
236 scoped_ptr<gpu::TransferBuffer> transfer_buffer(new gpu::TransferBuffer( 275 return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
237 cmd_helper.get())); 276
238 277 if (current_surface != new_surface &&
239 command_buffer_.reset(command_buffer.release()); 278 new_surface->is_current_in_some_thread())
240 transfer_buffer_.reset(transfer_buffer.release()); 279 return ts->ReturnError(EGL_BAD_ACCESS, EGL_FALSE);
241 gles2_cmd_helper_.reset(cmd_helper.release()); 280
242 surface_.reset(new Surface(win)); 281 if (!Context::MakeCurrent(
243 282 current_context,
244 return surface_.get(); 283 current_context ? current_surface->gl_surface() : nullptr,
245 } 284 new_context, new_context ? new_surface->gl_surface() : nullptr))
246 285 return ts->ReturnError(EGL_BAD_MATCH, EGL_FALSE);
247 void Display::DestroySurface(EGLSurface surface) { 286
248 DCHECK(IsValidSurface(surface)); 287 accr.SetCurrent(new_surface, new_context);
249 executor_.reset(); 288 return ts->ReturnSuccess(EGL_TRUE);
250 if (decoder_.get()) { 289 }
251 decoder_->Destroy(true); 290
252 } 291 EGLBoolean Display::SwapBuffers(ThreadState* ts, EGLSurface sfe) {
253 decoder_.reset(); 292 base::AutoLock auto_lock(lock_);
254 gl_surface_ = NULL; 293 if (!is_initialized_)
255 gl_context_ = NULL; 294 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
256 surface_.reset(); 295 egl::Surface* surface = GetSurface(sfe);
257 } 296 if (!surface)
258 297 return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
259 void Display::SwapBuffers(EGLSurface surface) { 298 if (ts->current_surface() != surface)
260 DCHECK(IsValidSurface(surface)); 299 return ts->ReturnError(EGL_BAD_SURFACE, EGL_FALSE);
261 context_->SwapBuffers(); 300 ts->current_context()->FlushAndSwapBuffers(surface->gl_surface());
262 } 301 return ts->ReturnSuccess(EGL_TRUE);
263 302 }
264 bool Display::IsValidContext(EGLContext ctx) { 303
265 return (ctx != NULL) && (ctx == context_.get()); 304 EGLContext Display::CreateContext(ThreadState* ts,
266 } 305 EGLConfig cfg,
267
268 EGLContext Display::CreateContext(EGLConfig config,
269 EGLContext share_ctx, 306 EGLContext share_ctx,
270 const EGLint* attrib_list) { 307 const EGLint* attrib_list) {
271 DCHECK(IsValidConfig(config)); 308 base::AutoLock auto_lock(lock_);
272 // TODO(alokp): Add support for shared contexts. 309 if (!is_initialized_)
273 if (share_ctx != NULL) 310 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_NO_CONTEXT);
274 return EGL_NO_CONTEXT; 311 if (share_ctx != EGL_NO_CONTEXT) {
275 312 egl::Context* share_context = GetContext(share_ctx);
276 DCHECK(command_buffer_ != NULL); 313 if (!share_context)
277 DCHECK(transfer_buffer_.get()); 314 return ts->ReturnError(EGL_BAD_CONTEXT, EGL_NO_CONTEXT);
278 315 // TODO(alokp): Add support for shared contexts.
279 bool bind_generates_resources = true; 316 return ts->ReturnError(EGL_BAD_MATCH, EGL_NO_CONTEXT);
280 bool lose_context_when_out_of_memory = false; 317 }
281 bool support_client_side_arrays = true; 318 if (!egl::Context::ValidateAttributeList(attrib_list))
282 319 return ts->ReturnError(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
283 context_.reset( 320 const egl::Config* config = GetConfig(cfg);
284 new gpu::gles2::GLES2Implementation(gles2_cmd_helper_.get(), 321 if (!config)
285 NULL, 322 return ts->ReturnError(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
286 transfer_buffer_.get(), 323 scoped_refptr<Context> context(new Context(this, config));
287 bind_generates_resources, 324 if (!context)
288 lose_context_when_out_of_memory, 325 return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
289 support_client_side_arrays, 326 contexts_.emplace_back(context.get());
290 this)); 327 return ts->ReturnSuccess<EGLContext>(context.get());
291 328 }
292 if (!context_->Initialize( 329
293 kTransferBufferSize, 330 EGLBoolean Display::DestroyContext(ThreadState* ts, EGLContext ctx) {
294 kTransferBufferSize / 2, 331 base::AutoLock auto_lock(lock_);
295 kTransferBufferSize * 2, 332 if (!is_initialized_)
296 gpu::gles2::GLES2Implementation::kNoLimit)) { 333 return ts->ReturnError(EGL_NOT_INITIALIZED, EGL_FALSE);
297 return EGL_NO_CONTEXT; 334 auto it = std::find(contexts_.begin(), contexts_.end(), ctx);
298 } 335 if (it == contexts_.end())
299 336 return ts->ReturnError(EGL_BAD_CONTEXT, EGL_FALSE);
300 context_->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets"); 337 (*it)->MarkDestroyed();
301 context_->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs"); 338 contexts_.erase(it);
302 339 return ts->ReturnSuccess(EGL_TRUE);
303 return context_.get();
304 }
305
306 void Display::DestroyContext(EGLContext ctx) {
307 DCHECK(IsValidContext(ctx));
308 context_.reset();
309 transfer_buffer_.reset();
310 }
311
312 bool Display::MakeCurrent(EGLSurface draw, EGLSurface read, EGLContext ctx) {
313 if (ctx == EGL_NO_CONTEXT) {
314 gles2::SetGLContext(NULL);
315 } else {
316 DCHECK(IsValidSurface(draw));
317 DCHECK(IsValidSurface(read));
318 DCHECK(IsValidContext(ctx));
319 gles2::SetGLContext(context_.get());
320 gl_context_->MakeCurrent(gl_surface_.get());
321 }
322 return true;
323 }
324
325 gpu::Capabilities Display::GetCapabilities() {
326 return decoder_->GetCapabilities();
327 }
328
329 int32_t Display::CreateImage(ClientBuffer buffer,
330 size_t width,
331 size_t height,
332 unsigned internalformat) {
333 NOTIMPLEMENTED();
334 return -1;
335 }
336
337 void Display::DestroyImage(int32_t id) {
338 NOTIMPLEMENTED();
339 }
340
341 int32_t Display::CreateGpuMemoryBufferImage(size_t width,
342 size_t height,
343 unsigned internalformat,
344 unsigned usage) {
345 NOTIMPLEMENTED();
346 return -1;
347 }
348
349 void Display::SignalQuery(uint32_t query, const base::Closure& callback) {
350 NOTIMPLEMENTED();
351 }
352
353 void Display::SetLock(base::Lock*) {
354 NOTIMPLEMENTED();
355 }
356
357 bool Display::IsGpuChannelLost() {
358 NOTIMPLEMENTED();
359 return false;
360 }
361
362 void Display::EnsureWorkVisible() {
363 // This is only relevant for out-of-process command buffers.
364 }
365
366 gpu::CommandBufferNamespace Display::GetNamespaceID() const {
367 return gpu::CommandBufferNamespace::IN_PROCESS;
368 }
369
370 gpu::CommandBufferId Display::GetCommandBufferID() const {
371 return gpu::CommandBufferId();
372 }
373
374 int32_t Display::GetExtraCommandBufferData() const {
375 return 0;
376 } 340 }
377 341
378 uint64_t Display::GenerateFenceSyncRelease() { 342 uint64_t Display::GenerateFenceSyncRelease() {
343 base::AutoLock auto_lock(lock_);
379 return next_fence_sync_release_++; 344 return next_fence_sync_release_++;
380 } 345 }
381 346
382 bool Display::IsFenceSyncRelease(uint64_t release) { 347 bool Display::IsFenceSyncRelease(uint64_t release) {
348 base::AutoLock auto_lock(lock_);
383 return release > 0 && release < next_fence_sync_release_; 349 return release > 0 && release < next_fence_sync_release_;
384 } 350 }
385 351
386 bool Display::IsFenceSyncFlushed(uint64_t release) { 352 bool Display::IsFenceSyncFlushed(uint64_t release) {
387 return IsFenceSyncRelease(release); 353 return IsFenceSyncRelease(release);
388 } 354 }
389 355
390 bool Display::IsFenceSyncFlushReceived(uint64_t release) { 356 bool Display::IsFenceSyncFlushReceived(uint64_t release) {
391 return IsFenceSyncRelease(release); 357 return IsFenceSyncRelease(release);
392 } 358 }
393 359
394 void Display::SignalSyncToken(const gpu::SyncToken& sync_token, 360 void Display::InitializeConfigsIfNeeded() {
395 const base::Closure& callback) { 361 lock_.AssertAcquired();
396 NOTIMPLEMENTED(); 362 if (!configs_[0]) {
363 // The interface offers separate configs for window and pbuffer.
364 // This way we can record the client intention at context creation time.
365 // The GL implementation (gfx::GLContext and gfx::GLSurface) needs this
366 // distinction when creating a context.
367 configs_[0].reset(new Config(EGL_WINDOW_BIT));
368 configs_[1].reset(new Config(EGL_PBUFFER_BIT));
369 }
397 } 370 }
398 371
399 bool Display::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) { 372 const Config* Display::GetConfig(EGLConfig cfg) {
400 return false; 373 lock_.AssertAcquired();
374 for (const auto& config : configs_) {
375 if (config.get() == cfg)
376 return config.get();
377 }
378 return nullptr;
379 }
380
381 Surface* Display::GetSurface(EGLSurface surface) {
382 lock_.AssertAcquired();
383 auto it = std::find(surfaces_.begin(), surfaces_.end(), surface);
384 if (it == surfaces_.end())
385 return nullptr;
386 return it->get();
387 }
388
389 Context* Display::GetContext(EGLContext context) {
390 lock_.AssertAcquired();
391 auto it = std::find(contexts_.begin(), contexts_.end(), context);
392 if (it == contexts_.end())
393 return nullptr;
394 return it->get();
401 } 395 }
402 396
403 } // namespace egl 397 } // namespace egl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698