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

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

Powered by Google App Engine
This is Rietveld 408576698