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

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

Powered by Google App Engine
This is Rietveld 408576698