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

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

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