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

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

Issue 1714883002: command_buffer_gles2: Implement EGL default Display as a global object (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@command_buffer_gles2-multiple-contexts
Patch Set: 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
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "gpu/gles2_conform_support/egl/context.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "gpu/command_buffer/client/gles2_implementation.h"
10 #include "gpu/command_buffer/client/gles2_lib.h"
11 #include "gpu/command_buffer/client/transfer_buffer.h"
12 #include "gpu/command_buffer/common/value_state.h"
13 #include "gpu/command_buffer/service/context_group.h"
14 #include "gpu/command_buffer/service/mailbox_manager.h"
15 #include "gpu/command_buffer/service/memory_tracking.h"
16 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
17 #include "gpu/command_buffer/service/valuebuffer_manager.h"
18 #include "gpu/gles2_conform_support/egl/config.h"
19 #include "gpu/gles2_conform_support/egl/display.h"
20 #include "gpu/gles2_conform_support/egl/surface.h"
21 #include "gpu/gles2_conform_support/egl/thread_state.h"
22
23 namespace {
24 const int32_t kCommandBufferSize = 1024 * 1024;
25 const int32_t kTransferBufferSize = 512 * 1024;
26 const bool kBindGeneratesResources = true;
27 const bool kLoseContextWhenOutOfMemory = false;
28 const bool kSupportClientSideArrays = true;
29 }
30
31 namespace egl {
32 Context::Context(Display* display, const Config* config)
33 : display_(display), config_(config), is_current_in_some_thread_(false) {}
34
35 Context::~Context() {
36 // We might not have a surface, so we must lose the context.
37 // Cleanup will execute GL commands otherwise.
38 if (!WasContextLost())
39 MarkContextLost();
40 Cleanup();
41 }
42
43 void Context::SetDestroyed(Surface* current_surface_if_own) {
44 if (WasContextLost())
45 return;
46 if (!client_gl_context_)
47 return;
48 if (!current_surface_if_own)
49 return;
50 if (!gl_context_->MakeCurrent(current_surface_if_own->gl_surface()))
51 return;
52 client_gl_context_->Flush();
53 }
54
55 void Context::FlushAndSwapBuffers(Surface* current_surface) {
56 if (WasContextLost())
57 return;
58 if (!client_gl_context_)
59 return;
60 if (!gl_context_->MakeCurrent(current_surface->gl_surface())) {
61 MarkContextLost();
62 return;
63 }
64 client_gl_context_->Flush();
65 current_surface->gl_surface()->SwapBuffers();
66 }
67
68 void Context::MakeCurrentRelease(Surface* current_surface) {
69 // MakeCurrentRelease always succeeds.
70 is_current_in_some_thread_ = false;
71 if (WasContextLost())
72 return;
73 if (!gl_context_->MakeCurrent(current_surface->gl_surface())) {
74 MarkContextLost();
75 return;
76 }
77 client_gl_context_->Flush();
78 decoder_->SetSurface(nullptr);
79 decoder_->ReleaseCurrent();
80 }
81
82 bool Context::MakeCurrentSwitchSurface(Surface* current_surface,
83 Surface* new_surface) {
84 if (WasContextLost())
85 return false;
86 if (!IsCompatibleSurface(new_surface->gl_surface()))
87 return false;
88 if (!gl_context_->MakeCurrent(current_surface->gl_surface())) {
89 MarkContextLost();
90 return false;
91 }
92 client_gl_context_->Flush();
93 if (current_surface != new_surface)
94 decoder_->SetSurface(new_surface->gl_surface());
95 if (!decoder_->MakeCurrent()) {
96 MarkContextLost();
97 return false;
98 }
99 return true;
100 }
101
102 bool Context::MakeCurrent(Surface* new_surface) {
103 DCHECK(new_surface);
104 if (WasContextLost())
105 return false;
106 if (!IsCompatibleSurface(new_surface->gl_surface()))
107 return false;
108 if (client_gl_context_) {
109 if (!gl_context_->MakeCurrent(new_surface->gl_surface())) {
110 MarkContextLost();
111 return false;
112 }
113 decoder_->SetSurface(new_surface->gl_surface());
114 if (!decoder_->MakeCurrent()) {
115 MarkContextLost();
116 return false;
117 }
118 is_current_in_some_thread_ = true;
119 return true;
120 }
121 gfx::GLSurface* gl_surface = new_surface->gl_surface();
122 scoped_refptr<gpu::TransferBufferManager> transfer_buffer_manager(
123 new gpu::TransferBufferManager(nullptr));
124 transfer_buffer_manager->Initialize();
125
126 scoped_ptr<gpu::CommandBufferService> command_buffer(
127 new gpu::CommandBufferService(transfer_buffer_manager.get()));
128 if (!command_buffer->Initialize())
129 return false;
130
131 scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
132 NULL, NULL, new gpu::gles2::ShaderTranslatorCache,
133 new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true));
134
135 scoped_ptr<gpu::gles2::GLES2Decoder> decoder(
136 gpu::gles2::GLES2Decoder::Create(group.get()));
137 if (!decoder.get())
138 return false;
139
140 scoped_ptr<gpu::GpuScheduler> gpu_scheduler(new gpu::GpuScheduler(
141 command_buffer.get(), decoder.get(), decoder.get()));
142
143 decoder->set_engine(gpu_scheduler.get());
144
145 scoped_refptr<gfx::GLContext> gl_context(gfx::GLContext::CreateGLContext(
146 nullptr, gl_surface, gfx::PreferDiscreteGpu));
147 if (!gl_context)
148 return false;
149
150 gl_context->MakeCurrent(gl_surface);
151
152 gpu::gles2::ContextCreationAttribHelper helper;
153 config_->GetAttrib(EGL_ALPHA_SIZE, &helper.alpha_size);
154 config_->GetAttrib(EGL_BLUE_SIZE, &helper.blue_size);
155 config_->GetAttrib(EGL_GREEN_SIZE, &helper.green_size);
156 config_->GetAttrib(EGL_RED_SIZE, &helper.red_size);
157 config_->GetAttrib(EGL_DEPTH_SIZE, &helper.depth_size);
158 config_->GetAttrib(EGL_STENCIL_SIZE, &helper.stencil_size);
159 config_->GetAttrib(EGL_SAMPLES, &helper.samples);
160 config_->GetAttrib(EGL_SAMPLE_BUFFERS, &helper.sample_buffers);
161
162 helper.buffer_preserved = false;
163 helper.bind_generates_resource = kBindGeneratesResources;
164 helper.fail_if_major_perf_caveat = false;
165 helper.lose_context_when_out_of_memory = kLoseContextWhenOutOfMemory;
166 helper.context_type = gpu::gles2::CONTEXT_TYPE_OPENGLES2;
167 std::vector<int32_t> attribs;
168 helper.Serialize(&attribs);
169
170 if (!decoder->Initialize(gl_surface, gl_context.get(),
171 gl_surface->IsOffscreen(), gl_surface->GetSize(),
172 gpu::gles2::DisallowedFeatures(), attribs)) {
173 return false;
174 }
175
176 command_buffer->SetPutOffsetChangeCallback(base::Bind(
177 &gpu::GpuScheduler::PutChanged, base::Unretained(gpu_scheduler.get())));
178 command_buffer->SetGetBufferChangeCallback(base::Bind(
179 &gpu::GpuScheduler::SetGetBuffer, base::Unretained(gpu_scheduler.get())));
180
181 scoped_ptr<gpu::gles2::GLES2CmdHelper> gles2_cmd_helper(
182 new gpu::gles2::GLES2CmdHelper(command_buffer.get()));
183 if (!gles2_cmd_helper->Initialize(kCommandBufferSize)) {
184 decoder->Destroy(true);
185 return false;
186 }
187
188 scoped_ptr<gpu::TransferBuffer> transfer_buffer(
189 new gpu::TransferBuffer(gles2_cmd_helper.get()));
190
191 gles2_cmd_helper_.reset(gles2_cmd_helper.release());
192 transfer_buffer_.reset(transfer_buffer.release());
193 command_buffer_.reset(command_buffer.release());
194 gpu_scheduler_.reset(gpu_scheduler.release());
195 decoder_.reset(decoder.release());
196 gl_context_ = gl_context.get();
197
198 scoped_ptr<gpu::gles2::GLES2Implementation> context(
199 new gpu::gles2::GLES2Implementation(
200 gles2_cmd_helper_.get(), nullptr, transfer_buffer_.get(),
201 kBindGeneratesResources, kLoseContextWhenOutOfMemory,
202 kSupportClientSideArrays, this));
203
204 if (!context->Initialize(kTransferBufferSize, kTransferBufferSize / 2,
205 kTransferBufferSize * 2,
206 gpu::gles2::GLES2Implementation::kNoLimit)) {
207 Cleanup();
208 return false;
209 }
210
211 context->EnableFeatureCHROMIUM("pepper3d_allow_buffers_on_multiple_targets");
212 context->EnableFeatureCHROMIUM("pepper3d_support_fixed_attribs");
213 client_gl_context_.reset(context.release());
214 is_current_in_some_thread_ = true;
215 return true;
216 }
217
218 gfx::GLContext* Context::gl_context() const {
219 return gl_context_.get();
220 }
221
222 gpu::gles2::GLES2Interface* Context::client_gl_context() const {
223 return client_gl_context_.get();
224 }
225
226 bool Context::ValidateAttributeList(const EGLint* attrib_list) {
227 if (attrib_list) {
228 for (int i = 0; attrib_list[i] != EGL_NONE; attrib_list += 2) {
229 switch (attrib_list[i]) {
230 case EGL_CONTEXT_CLIENT_VERSION:
231 break;
232 default:
233 return false;
234 }
235 }
236 }
237 return true;
238 }
239
240 gpu::Capabilities Context::GetCapabilities() {
241 return decoder_->GetCapabilities();
242 }
243
244 int32_t Context::CreateImage(ClientBuffer buffer,
245 size_t width,
246 size_t height,
247 unsigned internalformat) {
248 NOTIMPLEMENTED();
249 return -1;
250 }
251
252 void Context::DestroyImage(int32_t id) {
253 NOTIMPLEMENTED();
254 }
255
256 int32_t Context::CreateGpuMemoryBufferImage(size_t width,
257 size_t height,
258 unsigned internalformat,
259 unsigned usage) {
260 NOTIMPLEMENTED();
261 return -1;
262 }
263
264 void Context::SignalQuery(uint32_t query, const base::Closure& callback) {
265 NOTIMPLEMENTED();
266 }
267
268 void Context::SetLock(base::Lock*) {
269 NOTIMPLEMENTED();
270 }
271
272 bool Context::IsGpuChannelLost() {
273 NOTIMPLEMENTED();
274 return false;
275 }
276
277 void Context::EnsureWorkVisible() {
278 // This is only relevant for out-of-process command buffers.
279 }
280
281 gpu::CommandBufferNamespace Context::GetNamespaceID() const {
282 return gpu::CommandBufferNamespace::IN_PROCESS;
283 }
284
285 uint64_t Context::GetCommandBufferID() const {
286 return 0;
287 }
288
289 int32_t Context::GetExtraCommandBufferData() const {
290 return 0;
291 }
292
293 uint64_t Context::GenerateFenceSyncRelease() {
294 return display_->GenerateFenceSyncRelease();
295 }
296
297 bool Context::IsFenceSyncRelease(uint64_t release) {
298 return display_->IsFenceSyncRelease(release);
299 }
300
301 bool Context::IsFenceSyncFlushed(uint64_t release) {
302 return display_->IsFenceSyncFlushed(release);
303 }
304
305 bool Context::IsFenceSyncFlushReceived(uint64_t release) {
306 return display_->IsFenceSyncFlushReceived(release);
307 }
308
309 void Context::SignalSyncToken(const gpu::SyncToken& sync_token,
310 const base::Closure& callback) {
311 NOTIMPLEMENTED();
312 }
313
314 bool Context::CanWaitUnverifiedSyncToken(const gpu::SyncToken* sync_token) {
315 return false;
316 }
317
318 void Context::Cleanup() {
319 client_gl_context_.reset();
320 gl_context_ = nullptr;
321
322 transfer_buffer_.reset();
323 gpu_scheduler_.reset();
324 if (decoder_)
325 decoder_->Destroy(false);
326 gles2_cmd_helper_.reset();
327 command_buffer_.reset();
328 }
329
330 void Context::MarkContextLost() {
331 if (!decoder_)
332 return;
333 decoder_->MarkContextLost(gpu::error::kMakeCurrentFailed);
334 }
335
336 bool Context::WasContextLost() const {
337 return decoder_ && decoder_->WasContextLost();
338 }
339
340 bool Context::IsCompatibleSurface(gfx::GLSurface* gl_surface) {
341 EGLint value = EGL_NONE;
342 config_->GetAttrib(EGL_SURFACE_TYPE, &value);
343 bool config_is_offscreen = (value & EGL_PBUFFER_BIT) != 0;
344 return gl_surface->IsOffscreen() == config_is_offscreen;
345 }
346
347 } // namespace egl
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698