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

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

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