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

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

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