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

Side by Side Diff: ui/gl/gl_surface_ozone.cc

Issue 2088453003: Move GLSurface and rename source files. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix GYP path. Created 4 years, 6 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 | « ui/gl/gl_surface_ozone.h ('k') | ui/gl/gl_surface_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "ui/gl/gl_surface_ozone.h"
6
7 #include <stddef.h>
8
9 #include <vector>
10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/macros.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/threading/worker_pool.h"
19 #include "ui/gl/egl_util.h"
20 #include "ui/gl/gl_context.h"
21 #include "ui/gl/gl_image.h"
22 #include "ui/gl/gl_image_ozone_native_pixmap.h"
23 #include "ui/gl/gl_implementation.h"
24 #include "ui/gl/gl_surface_egl.h"
25 #include "ui/gl/gl_surface_osmesa.h"
26 #include "ui/gl/gl_surface_overlay.h"
27 #include "ui/gl/gl_surface_stub.h"
28 #include "ui/gl/scoped_binders.h"
29 #include "ui/gl/scoped_make_current.h"
30 #include "ui/ozone/public/native_pixmap.h"
31 #include "ui/ozone/public/ozone_platform.h"
32 #include "ui/ozone/public/surface_factory_ozone.h"
33 #include "ui/ozone/public/surface_ozone_egl.h"
34
35 namespace gl {
36
37 namespace {
38
39 // Helper function for base::Bind to create callback to eglChooseConfig.
40 bool EglChooseConfig(EGLDisplay display,
41 const int32_t* attribs,
42 EGLConfig* configs,
43 int32_t config_size,
44 int32_t* num_configs) {
45 return eglChooseConfig(display, attribs, configs, config_size, num_configs);
46 }
47
48 // Helper function for base::Bind to create callback to eglGetConfigAttrib.
49 bool EglGetConfigAttribute(EGLDisplay display,
50 EGLConfig config,
51 int32_t attribute,
52 int32_t* value) {
53 return eglGetConfigAttrib(display, config, attribute, value);
54 }
55
56 // Populates EglConfigCallbacks with appropriate callbacks.
57 ui::EglConfigCallbacks GetEglConfigCallbacks(EGLDisplay display) {
58 ui::EglConfigCallbacks callbacks;
59 callbacks.choose_config = base::Bind(EglChooseConfig, display);
60 callbacks.get_config_attribute = base::Bind(EglGetConfigAttribute, display);
61 callbacks.get_last_error_string = base::Bind(&ui::GetLastEGLErrorString);
62 return callbacks;
63 }
64
65 void WaitForFence(EGLDisplay display, EGLSyncKHR fence) {
66 eglClientWaitSyncKHR(display, fence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
67 EGL_FOREVER_KHR);
68 }
69
70 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow.
71 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL {
72 public:
73 GLSurfaceOzoneEGL(std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface,
74 gfx::AcceleratedWidget widget);
75
76 // GLSurface:
77 bool Initialize(GLSurface::Format format) override;
78 bool Resize(const gfx::Size& size,
79 float scale_factor,
80 bool has_alpha) override;
81 gfx::SwapResult SwapBuffers() override;
82 bool ScheduleOverlayPlane(int z_order,
83 gfx::OverlayTransform transform,
84 GLImage* image,
85 const gfx::Rect& bounds_rect,
86 const gfx::RectF& crop_rect) override;
87 EGLConfig GetConfig() override;
88
89 private:
90 using NativeViewGLSurfaceEGL::Initialize;
91
92 ~GLSurfaceOzoneEGL() override;
93
94 bool ReinitializeNativeSurface();
95
96 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
97 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
98 gfx::AcceleratedWidget widget_;
99
100 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL);
101 };
102
103 GLSurfaceOzoneEGL::GLSurfaceOzoneEGL(
104 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface,
105 gfx::AcceleratedWidget widget)
106 : NativeViewGLSurfaceEGL(ozone_surface->GetNativeWindow()),
107 ozone_surface_(std::move(ozone_surface)),
108 widget_(widget) {}
109
110 bool GLSurfaceOzoneEGL::Initialize(GLSurface::Format format) {
111 format_ = format;
112 return Initialize(ozone_surface_->CreateVSyncProvider());
113 }
114
115 bool GLSurfaceOzoneEGL::Resize(const gfx::Size& size,
116 float scale_factor,
117 bool has_alpha) {
118 if (!ozone_surface_->ResizeNativeWindow(size)) {
119 if (!ReinitializeNativeSurface() ||
120 !ozone_surface_->ResizeNativeWindow(size))
121 return false;
122 }
123
124 return NativeViewGLSurfaceEGL::Resize(size, scale_factor, has_alpha);
125 }
126
127 gfx::SwapResult GLSurfaceOzoneEGL::SwapBuffers() {
128 gfx::SwapResult result = NativeViewGLSurfaceEGL::SwapBuffers();
129 if (result != gfx::SwapResult::SWAP_ACK)
130 return result;
131
132 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
133 : gfx::SwapResult::SWAP_FAILED;
134 }
135
136 bool GLSurfaceOzoneEGL::ScheduleOverlayPlane(int z_order,
137 gfx::OverlayTransform transform,
138 GLImage* image,
139 const gfx::Rect& bounds_rect,
140 const gfx::RectF& crop_rect) {
141 return image->ScheduleOverlayPlane(widget_, z_order, transform, bounds_rect,
142 crop_rect);
143 }
144
145 EGLConfig GLSurfaceOzoneEGL::GetConfig() {
146 if (!config_) {
147 ui::EglConfigCallbacks callbacks = GetEglConfigCallbacks(GetDisplay());
148 config_ = ozone_surface_->GetEGLSurfaceConfig(callbacks);
149 }
150 if (config_)
151 return config_;
152 return NativeViewGLSurfaceEGL::GetConfig();
153 }
154
155 GLSurfaceOzoneEGL::~GLSurfaceOzoneEGL() {
156 Destroy(); // The EGL surface must be destroyed before SurfaceOzone.
157 }
158
159 bool GLSurfaceOzoneEGL::ReinitializeNativeSurface() {
160 std::unique_ptr<ui::ScopedMakeCurrent> scoped_make_current;
161 GLContext* current_context = GLContext::GetCurrent();
162 bool was_current = current_context && current_context->IsCurrent(this);
163 if (was_current) {
164 scoped_make_current.reset(new ui::ScopedMakeCurrent(current_context, this));
165 }
166
167 Destroy();
168 ozone_surface_ = ui::OzonePlatform::GetInstance()
169 ->GetSurfaceFactoryOzone()
170 ->CreateEGLSurfaceForWidget(widget_);
171 if (!ozone_surface_) {
172 LOG(ERROR) << "Failed to create native surface.";
173 return false;
174 }
175
176 window_ = ozone_surface_->GetNativeWindow();
177 if (!Initialize(format_)) {
178 LOG(ERROR) << "Failed to initialize.";
179 return false;
180 }
181
182 return true;
183 }
184
185 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL {
186 public:
187 GLSurfaceOzoneSurfaceless(std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface,
188 gfx::AcceleratedWidget widget);
189
190 // GLSurface:
191 bool Initialize(GLSurface::Format format) override;
192 bool Resize(const gfx::Size& size,
193 float scale_factor,
194 bool has_alpha) override;
195 gfx::SwapResult SwapBuffers() override;
196 bool ScheduleOverlayPlane(int z_order,
197 gfx::OverlayTransform transform,
198 GLImage* image,
199 const gfx::Rect& bounds_rect,
200 const gfx::RectF& crop_rect) override;
201 bool IsOffscreen() override;
202 gfx::VSyncProvider* GetVSyncProvider() override;
203 bool SupportsAsyncSwap() override;
204 bool SupportsPostSubBuffer() override;
205 gfx::SwapResult PostSubBuffer(int x, int y, int width, int height) override;
206 void SwapBuffersAsync(const SwapCompletionCallback& callback) override;
207 void PostSubBufferAsync(int x,
208 int y,
209 int width,
210 int height,
211 const SwapCompletionCallback& callback) override;
212 EGLConfig GetConfig() override;
213
214 protected:
215 struct PendingFrame {
216 PendingFrame();
217
218 bool ScheduleOverlayPlanes(gfx::AcceleratedWidget widget);
219
220 bool ready;
221 std::vector<GLSurfaceOverlay> overlays;
222 SwapCompletionCallback callback;
223 };
224
225 ~GLSurfaceOzoneSurfaceless() override;
226
227 void SubmitFrame();
228
229 EGLSyncKHR InsertFence();
230 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame);
231
232 void SwapCompleted(const SwapCompletionCallback& callback,
233 gfx::SwapResult result);
234
235 // The native surface. Deleting this is allowed to free the EGLNativeWindow.
236 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface_;
237 gfx::AcceleratedWidget widget_;
238 std::unique_ptr<gfx::VSyncProvider> vsync_provider_;
239 ScopedVector<PendingFrame> unsubmitted_frames_;
240 bool has_implicit_external_sync_;
241 bool last_swap_buffers_result_;
242 bool swap_buffers_pending_;
243
244 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_;
245
246 private:
247 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless);
248 };
249
250 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {}
251
252 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes(
253 gfx::AcceleratedWidget widget) {
254 for (const auto& overlay : overlays)
255 if (!overlay.ScheduleOverlayPlane(widget))
256 return false;
257 return true;
258 }
259
260 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless(
261 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface,
262 gfx::AcceleratedWidget widget)
263 : SurfacelessEGL(gfx::Size()),
264 ozone_surface_(std::move(ozone_surface)),
265 widget_(widget),
266 has_implicit_external_sync_(
267 HasEGLExtension("EGL_ARM_implicit_external_sync")),
268 last_swap_buffers_result_(true),
269 swap_buffers_pending_(false),
270 weak_factory_(this) {
271 unsubmitted_frames_.push_back(new PendingFrame());
272 }
273
274 bool GLSurfaceOzoneSurfaceless::Initialize(GLSurface::Format format) {
275 if (!SurfacelessEGL::Initialize(format))
276 return false;
277 vsync_provider_ = ozone_surface_->CreateVSyncProvider();
278 if (!vsync_provider_)
279 return false;
280 return true;
281 }
282
283 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size,
284 float scale_factor,
285 bool has_alpha) {
286 if (!ozone_surface_->ResizeNativeWindow(size))
287 return false;
288
289 return SurfacelessEGL::Resize(size, scale_factor, has_alpha);
290 }
291
292 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() {
293 glFlush();
294 // TODO: the following should be replaced by a per surface flush as it gets
295 // implemented in GL drivers.
296 if (has_implicit_external_sync_) {
297 EGLSyncKHR fence = InsertFence();
298 if (!fence)
299 return gfx::SwapResult::SWAP_FAILED;
300
301 EGLDisplay display = GetDisplay();
302 WaitForFence(display, fence);
303 eglDestroySyncKHR(display, fence);
304 }
305
306 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_);
307 unsubmitted_frames_.back()->overlays.clear();
308
309 if (ozone_surface_->IsUniversalDisplayLinkDevice())
310 glFinish();
311
312 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK
313 : gfx::SwapResult::SWAP_FAILED;
314 }
315
316 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane(
317 int z_order,
318 gfx::OverlayTransform transform,
319 GLImage* image,
320 const gfx::Rect& bounds_rect,
321 const gfx::RectF& crop_rect) {
322 unsubmitted_frames_.back()->overlays.push_back(
323 GLSurfaceOverlay(z_order, transform, image, bounds_rect, crop_rect));
324 return true;
325 }
326
327 bool GLSurfaceOzoneSurfaceless::IsOffscreen() {
328 return false;
329 }
330
331 gfx::VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() {
332 return vsync_provider_.get();
333 }
334
335 bool GLSurfaceOzoneSurfaceless::SupportsAsyncSwap() {
336 return true;
337 }
338
339 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() {
340 return true;
341 }
342
343 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x,
344 int y,
345 int width,
346 int height) {
347 // The actual sub buffer handling is handled at higher layers.
348 NOTREACHED();
349 return gfx::SwapResult::SWAP_FAILED;
350 }
351
352 void GLSurfaceOzoneSurfaceless::SwapBuffersAsync(
353 const SwapCompletionCallback& callback) {
354 // If last swap failed, don't try to schedule new ones.
355 if (!last_swap_buffers_result_) {
356 callback.Run(gfx::SwapResult::SWAP_FAILED);
357 return;
358 }
359
360 glFlush();
361
362 SwapCompletionCallback surface_swap_callback =
363 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted,
364 weak_factory_.GetWeakPtr(), callback);
365
366 PendingFrame* frame = unsubmitted_frames_.back();
367 frame->callback = surface_swap_callback;
368 unsubmitted_frames_.push_back(new PendingFrame());
369
370 // TODO: the following should be replaced by a per surface flush as it gets
371 // implemented in GL drivers.
372 if (has_implicit_external_sync_) {
373 EGLSyncKHR fence = InsertFence();
374 if (!fence) {
375 callback.Run(gfx::SwapResult::SWAP_FAILED);
376 return;
377 }
378
379 base::Closure fence_wait_task =
380 base::Bind(&WaitForFence, GetDisplay(), fence);
381
382 base::Closure fence_retired_callback =
383 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired,
384 weak_factory_.GetWeakPtr(), fence, frame);
385
386 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task,
387 fence_retired_callback, false);
388 return; // Defer frame submission until fence signals.
389 }
390
391 frame->ready = true;
392 SubmitFrame();
393 }
394
395 void GLSurfaceOzoneSurfaceless::PostSubBufferAsync(
396 int x,
397 int y,
398 int width,
399 int height,
400 const SwapCompletionCallback& callback) {
401 // The actual sub buffer handling is handled at higher layers.
402 SwapBuffersAsync(callback);
403 }
404
405 EGLConfig GLSurfaceOzoneSurfaceless::GetConfig() {
406 if (!config_) {
407 ui::EglConfigCallbacks callbacks = GetEglConfigCallbacks(GetDisplay());
408 config_ = ozone_surface_->GetEGLSurfaceConfig(callbacks);
409 }
410 if (config_)
411 return config_;
412 return SurfacelessEGL::GetConfig();
413 }
414
415 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() {
416 Destroy(); // The EGL surface must be destroyed before SurfaceOzone.
417 }
418
419 void GLSurfaceOzoneSurfaceless::SubmitFrame() {
420 DCHECK(!unsubmitted_frames_.empty());
421
422 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) {
423 std::unique_ptr<PendingFrame> frame(unsubmitted_frames_.front());
424 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin());
425 swap_buffers_pending_ = true;
426
427 if (!frame->ScheduleOverlayPlanes(widget_)) {
428 // |callback| is a wrapper for SwapCompleted(). Call it to properly
429 // propagate the failed state.
430 frame->callback.Run(gfx::SwapResult::SWAP_FAILED);
431 return;
432 }
433
434 if (ozone_surface_->IsUniversalDisplayLinkDevice())
435 glFinish();
436
437 ozone_surface_->OnSwapBuffersAsync(frame->callback);
438 }
439 }
440
441 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence() {
442 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR,
443 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM,
444 EGL_NONE};
445 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list);
446 }
447
448 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence,
449 PendingFrame* frame) {
450 eglDestroySyncKHR(GetDisplay(), fence);
451 frame->ready = true;
452 SubmitFrame();
453 }
454
455 void GLSurfaceOzoneSurfaceless::SwapCompleted(
456 const SwapCompletionCallback& callback,
457 gfx::SwapResult result) {
458 callback.Run(result);
459 swap_buffers_pending_ = false;
460 if (result == gfx::SwapResult::SWAP_FAILED) {
461 last_swap_buffers_result_ = false;
462 return;
463 }
464
465 SubmitFrame();
466 }
467
468 // This provides surface-like semantics implemented through surfaceless.
469 // A framebuffer is bound automatically.
470 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl
471 : public GLSurfaceOzoneSurfaceless {
472 public:
473 GLSurfaceOzoneSurfacelessSurfaceImpl(
474 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface,
475 gfx::AcceleratedWidget widget);
476
477 // GLSurface:
478 unsigned int GetBackingFrameBufferObject() override;
479 bool OnMakeCurrent(GLContext* context) override;
480 bool Resize(const gfx::Size& size,
481 float scale_factor,
482 bool has_alpha) override;
483 bool SupportsPostSubBuffer() override;
484 gfx::SwapResult SwapBuffers() override;
485 void SwapBuffersAsync(const SwapCompletionCallback& callback) override;
486 void Destroy() override;
487 bool IsSurfaceless() const override;
488
489 private:
490 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override;
491
492 void BindFramebuffer();
493 bool CreatePixmaps();
494
495 scoped_refptr<GLContext> context_;
496 GLuint fbo_;
497 GLuint textures_[2];
498 scoped_refptr<GLImage> images_[2];
499 int current_surface_;
500 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl);
501 };
502
503 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl(
504 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface,
505 gfx::AcceleratedWidget widget)
506 : GLSurfaceOzoneSurfaceless(std::move(ozone_surface), widget),
507 context_(nullptr),
508 fbo_(0),
509 current_surface_(0) {
510 for (auto& texture : textures_)
511 texture = 0;
512 }
513
514 unsigned int
515 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() {
516 return fbo_;
517 }
518
519 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext* context) {
520 DCHECK(!context_ || context == context_);
521 context_ = context;
522 if (!fbo_) {
523 glGenFramebuffersEXT(1, &fbo_);
524 if (!fbo_)
525 return false;
526 glGenTextures(arraysize(textures_), textures_);
527 if (!CreatePixmaps())
528 return false;
529 }
530 BindFramebuffer();
531 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_);
532 return SurfacelessEGL::OnMakeCurrent(context);
533 }
534
535 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size,
536 float scale_factor,
537 bool has_alpha) {
538 if (size == GetSize())
539 return true;
540 // Alpha value isn't actually used in allocating buffers yet, so always use
541 // true instead.
542 return GLSurfaceOzoneSurfaceless::Resize(size, scale_factor, true) &&
543 CreatePixmaps();
544 }
545
546 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() {
547 return false;
548 }
549
550 gfx::SwapResult GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() {
551 if (!images_[current_surface_]->ScheduleOverlayPlane(
552 widget_, 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE,
553 gfx::Rect(GetSize()), gfx::RectF(1, 1)))
554 return gfx::SwapResult::SWAP_FAILED;
555 gfx::SwapResult result = GLSurfaceOzoneSurfaceless::SwapBuffers();
556 if (result != gfx::SwapResult::SWAP_ACK)
557 return result;
558 current_surface_ ^= 1;
559 BindFramebuffer();
560 return gfx::SwapResult::SWAP_ACK;
561 }
562
563 void GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync(
564 const SwapCompletionCallback& callback) {
565 if (!images_[current_surface_]->ScheduleOverlayPlane(
566 widget_, 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE,
567 gfx::Rect(GetSize()), gfx::RectF(1, 1))) {
568 callback.Run(gfx::SwapResult::SWAP_FAILED);
569 return;
570 }
571 GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback);
572 current_surface_ ^= 1;
573 BindFramebuffer();
574 }
575
576 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() {
577 if (!context_)
578 return;
579 scoped_refptr<GLContext> previous_context = GLContext::GetCurrent();
580 scoped_refptr<GLSurface> previous_surface;
581
582 bool was_current = previous_context && previous_context->IsCurrent(nullptr) &&
583 GLSurface::GetCurrent() == this;
584 if (!was_current) {
585 // Only take a reference to previous surface if it's not |this|
586 // because otherwise we can take a self reference from our own dtor.
587 previous_surface = GLSurface::GetCurrent();
588 context_->MakeCurrent(this);
589 }
590
591 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
592 if (fbo_) {
593 glDeleteTextures(arraysize(textures_), textures_);
594 for (auto& texture : textures_)
595 texture = 0;
596 glDeleteFramebuffersEXT(1, &fbo_);
597 fbo_ = 0;
598 }
599 for (auto image : images_) {
600 if (image)
601 image->Destroy(true);
602 }
603
604 if (!was_current) {
605 if (previous_context) {
606 previous_context->MakeCurrent(previous_surface.get());
607 } else {
608 context_->ReleaseCurrent(this);
609 }
610 }
611 }
612
613 bool GLSurfaceOzoneSurfacelessSurfaceImpl::IsSurfaceless() const {
614 return false;
615 }
616
617 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() {
618 Destroy();
619 }
620
621 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() {
622 ScopedFrameBufferBinder fb(fbo_);
623 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
624 textures_[current_surface_], 0);
625 }
626
627 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() {
628 if (!fbo_)
629 return true;
630 for (size_t i = 0; i < arraysize(textures_); i++) {
631 scoped_refptr<ui::NativePixmap> pixmap =
632 ui::OzonePlatform::GetInstance()
633 ->GetSurfaceFactoryOzone()
634 ->CreateNativePixmap(widget_, GetSize(),
635 gfx::BufferFormat::BGRA_8888,
636 gfx::BufferUsage::SCANOUT);
637 if (!pixmap)
638 return false;
639 scoped_refptr<GLImageOzoneNativePixmap> image =
640 new GLImageOzoneNativePixmap(GetSize(), GL_BGRA_EXT);
641 if (!image->Initialize(pixmap.get(), gfx::BufferFormat::BGRA_8888))
642 return false;
643 // Image must have Destroy() called before destruction.
644 if (images_[i])
645 images_[i]->Destroy(true);
646 images_[i] = image;
647 // Bind image to texture.
648 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]);
649 if (!images_[i]->BindTexImage(GL_TEXTURE_2D))
650 return false;
651 }
652 return true;
653 }
654
655 } // namespace
656
657 scoped_refptr<GLSurface> CreateViewGLSurfaceOzone(
658 gfx::AcceleratedWidget window) {
659 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone =
660 ui::OzonePlatform::GetInstance()
661 ->GetSurfaceFactoryOzone()
662 ->CreateEGLSurfaceForWidget(window);
663 if (!surface_ozone)
664 return nullptr;
665 return InitializeGLSurface(
666 new GLSurfaceOzoneEGL(std::move(surface_ozone), window));
667 }
668
669 scoped_refptr<GLSurface> CreateViewGLSurfaceOzoneSurfaceless(
670 gfx::AcceleratedWidget window) {
671 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone =
672 ui::OzonePlatform::GetInstance()
673 ->GetSurfaceFactoryOzone()
674 ->CreateSurfacelessEGLSurfaceForWidget(window);
675 if (!surface_ozone)
676 return nullptr;
677 return InitializeGLSurface(
678 new GLSurfaceOzoneSurfaceless(std::move(surface_ozone), window));
679 }
680
681 scoped_refptr<GLSurface> CreateViewGLSurfaceOzoneSurfacelessSurfaceImpl(
682 gfx::AcceleratedWidget window) {
683 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone =
684 ui::OzonePlatform::GetInstance()
685 ->GetSurfaceFactoryOzone()
686 ->CreateSurfacelessEGLSurfaceForWidget(window);
687 if (!surface_ozone)
688 return nullptr;
689 return InitializeGLSurface(new GLSurfaceOzoneSurfacelessSurfaceImpl(
690 std::move(surface_ozone), window));
691 }
692
693 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() {
694 return ui::OzonePlatform::GetInstance()
695 ->GetSurfaceFactoryOzone()
696 ->GetNativeDisplay();
697 }
698
699 } // namespace gl
OLDNEW
« no previous file with comments | « ui/gl/gl_surface_ozone.h ('k') | ui/gl/gl_surface_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698