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

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

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