OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 "ui/gl/init/gl_surface_ozone.h" | 5 #include "ui/gl/init/gl_surface_ozone.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 // Populates EglConfigCallbacks with appropriate callbacks. | 56 // Populates EglConfigCallbacks with appropriate callbacks. |
57 ui::EglConfigCallbacks GetEglConfigCallbacks(EGLDisplay display) { | 57 ui::EglConfigCallbacks GetEglConfigCallbacks(EGLDisplay display) { |
58 ui::EglConfigCallbacks callbacks; | 58 ui::EglConfigCallbacks callbacks; |
59 callbacks.choose_config = base::Bind(EglChooseConfig, display); | 59 callbacks.choose_config = base::Bind(EglChooseConfig, display); |
60 callbacks.get_config_attribute = base::Bind(EglGetConfigAttribute, display); | 60 callbacks.get_config_attribute = base::Bind(EglGetConfigAttribute, display); |
61 callbacks.get_last_error_string = base::Bind(&ui::GetLastEGLErrorString); | 61 callbacks.get_last_error_string = base::Bind(&ui::GetLastEGLErrorString); |
62 return callbacks; | 62 return callbacks; |
63 } | 63 } |
64 | 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. | 65 // A thin wrapper around GLSurfaceEGL that owns the EGLNativeWindow. |
71 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { | 66 class GL_EXPORT GLSurfaceOzoneEGL : public NativeViewGLSurfaceEGL { |
72 public: | 67 public: |
73 GLSurfaceOzoneEGL(std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 68 GLSurfaceOzoneEGL(std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
74 gfx::AcceleratedWidget widget); | 69 gfx::AcceleratedWidget widget); |
75 | 70 |
76 // GLSurface: | 71 // GLSurface: |
77 bool Initialize(GLSurface::Format format) override; | 72 bool Initialize(GLSurface::Format format) override; |
78 bool Resize(const gfx::Size& size, | 73 bool Resize(const gfx::Size& size, |
79 float scale_factor, | 74 float scale_factor, |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 170 |
176 window_ = ozone_surface_->GetNativeWindow(); | 171 window_ = ozone_surface_->GetNativeWindow(); |
177 if (!Initialize(format_)) { | 172 if (!Initialize(format_)) { |
178 LOG(ERROR) << "Failed to initialize."; | 173 LOG(ERROR) << "Failed to initialize."; |
179 return false; | 174 return false; |
180 } | 175 } |
181 | 176 |
182 return true; | 177 return true; |
183 } | 178 } |
184 | 179 |
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 void Flush(); | |
220 | |
221 bool ready; | |
222 std::vector<GLSurfaceOverlay> overlays; | |
223 SwapCompletionCallback callback; | |
224 }; | |
225 | |
226 ~GLSurfaceOzoneSurfaceless() override; | |
227 | |
228 void SubmitFrame(); | |
229 | |
230 EGLSyncKHR InsertFence(bool implicit); | |
231 void FenceRetired(EGLSyncKHR fence, PendingFrame* frame); | |
232 | |
233 void SwapCompleted(const SwapCompletionCallback& callback, | |
234 gfx::SwapResult result); | |
235 | |
236 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | |
237 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | |
238 gfx::AcceleratedWidget widget_; | |
239 std::unique_ptr<gfx::VSyncProvider> vsync_provider_; | |
240 ScopedVector<PendingFrame> unsubmitted_frames_; | |
241 bool has_implicit_external_sync_; | |
242 bool has_image_flush_external_; | |
243 bool last_swap_buffers_result_; | |
244 bool swap_buffers_pending_; | |
245 | |
246 base::WeakPtrFactory<GLSurfaceOzoneSurfaceless> weak_factory_; | |
247 | |
248 private: | |
249 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); | |
250 }; | |
251 | |
252 GLSurfaceOzoneSurfaceless::PendingFrame::PendingFrame() : ready(false) {} | |
253 | |
254 bool GLSurfaceOzoneSurfaceless::PendingFrame::ScheduleOverlayPlanes( | |
255 gfx::AcceleratedWidget widget) { | |
256 for (const auto& overlay : overlays) | |
257 if (!overlay.ScheduleOverlayPlane(widget)) | |
258 return false; | |
259 return true; | |
260 } | |
261 | |
262 void GLSurfaceOzoneSurfaceless::PendingFrame::Flush() { | |
263 for (const auto& overlay : overlays) | |
264 overlay.Flush(); | |
265 } | |
266 | |
267 GLSurfaceOzoneSurfaceless::GLSurfaceOzoneSurfaceless( | |
268 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, | |
269 gfx::AcceleratedWidget widget) | |
270 : SurfacelessEGL(gfx::Size()), | |
271 ozone_surface_(std::move(ozone_surface)), | |
272 widget_(widget), | |
273 has_implicit_external_sync_( | |
274 HasEGLExtension("EGL_ARM_implicit_external_sync")), | |
275 has_image_flush_external_( | |
276 HasEGLExtension("EGL_EXT_image_flush_external")), | |
277 last_swap_buffers_result_(true), | |
278 swap_buffers_pending_(false), | |
279 weak_factory_(this) { | |
280 unsubmitted_frames_.push_back(new PendingFrame()); | |
281 } | |
282 | |
283 bool GLSurfaceOzoneSurfaceless::Initialize(GLSurface::Format format) { | |
284 if (!SurfacelessEGL::Initialize(format)) | |
285 return false; | |
286 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); | |
287 if (!vsync_provider_) | |
288 return false; | |
289 return true; | |
290 } | |
291 | |
292 bool GLSurfaceOzoneSurfaceless::Resize(const gfx::Size& size, | |
293 float scale_factor, | |
294 bool has_alpha) { | |
295 if (!ozone_surface_->ResizeNativeWindow(size)) | |
296 return false; | |
297 | |
298 return SurfacelessEGL::Resize(size, scale_factor, has_alpha); | |
299 } | |
300 | |
301 gfx::SwapResult GLSurfaceOzoneSurfaceless::SwapBuffers() { | |
302 glFlush(); | |
303 | |
304 unsubmitted_frames_.back()->Flush(); | |
305 | |
306 // TODO: the following should be replaced by a per surface flush as it gets | |
307 // implemented in GL drivers. | |
308 if (has_implicit_external_sync_ || has_image_flush_external_) { | |
309 EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); | |
310 if (!fence) | |
311 return gfx::SwapResult::SWAP_FAILED; | |
312 | |
313 EGLDisplay display = GetDisplay(); | |
314 WaitForFence(display, fence); | |
315 eglDestroySyncKHR(display, fence); | |
316 } | |
317 | |
318 unsubmitted_frames_.back()->ScheduleOverlayPlanes(widget_); | |
319 unsubmitted_frames_.back()->overlays.clear(); | |
320 | |
321 if (ozone_surface_->IsUniversalDisplayLinkDevice()) | |
322 glFinish(); | |
323 | |
324 return ozone_surface_->OnSwapBuffers() ? gfx::SwapResult::SWAP_ACK | |
325 : gfx::SwapResult::SWAP_FAILED; | |
326 } | |
327 | |
328 bool GLSurfaceOzoneSurfaceless::ScheduleOverlayPlane( | |
329 int z_order, | |
330 gfx::OverlayTransform transform, | |
331 GLImage* image, | |
332 const gfx::Rect& bounds_rect, | |
333 const gfx::RectF& crop_rect) { | |
334 unsubmitted_frames_.back()->overlays.push_back( | |
335 GLSurfaceOverlay(z_order, transform, image, bounds_rect, crop_rect)); | |
336 return true; | |
337 } | |
338 | |
339 bool GLSurfaceOzoneSurfaceless::IsOffscreen() { | |
340 return false; | |
341 } | |
342 | |
343 gfx::VSyncProvider* GLSurfaceOzoneSurfaceless::GetVSyncProvider() { | |
344 return vsync_provider_.get(); | |
345 } | |
346 | |
347 bool GLSurfaceOzoneSurfaceless::SupportsAsyncSwap() { | |
348 return true; | |
349 } | |
350 | |
351 bool GLSurfaceOzoneSurfaceless::SupportsPostSubBuffer() { | |
352 return true; | |
353 } | |
354 | |
355 gfx::SwapResult GLSurfaceOzoneSurfaceless::PostSubBuffer(int x, | |
356 int y, | |
357 int width, | |
358 int height) { | |
359 // The actual sub buffer handling is handled at higher layers. | |
360 NOTREACHED(); | |
361 return gfx::SwapResult::SWAP_FAILED; | |
362 } | |
363 | |
364 void GLSurfaceOzoneSurfaceless::SwapBuffersAsync( | |
365 const SwapCompletionCallback& callback) { | |
366 // If last swap failed, don't try to schedule new ones. | |
367 if (!last_swap_buffers_result_) { | |
368 callback.Run(gfx::SwapResult::SWAP_FAILED); | |
369 return; | |
370 } | |
371 | |
372 glFlush(); | |
373 unsubmitted_frames_.back()->Flush(); | |
374 | |
375 SwapCompletionCallback surface_swap_callback = | |
376 base::Bind(&GLSurfaceOzoneSurfaceless::SwapCompleted, | |
377 weak_factory_.GetWeakPtr(), callback); | |
378 | |
379 PendingFrame* frame = unsubmitted_frames_.back(); | |
380 frame->callback = surface_swap_callback; | |
381 unsubmitted_frames_.push_back(new PendingFrame()); | |
382 | |
383 // TODO: the following should be replaced by a per surface flush as it gets | |
384 // implemented in GL drivers. | |
385 if (has_implicit_external_sync_ || has_image_flush_external_) { | |
386 EGLSyncKHR fence = InsertFence(has_implicit_external_sync_); | |
387 if (!fence) { | |
388 callback.Run(gfx::SwapResult::SWAP_FAILED); | |
389 return; | |
390 } | |
391 | |
392 base::Closure fence_wait_task = | |
393 base::Bind(&WaitForFence, GetDisplay(), fence); | |
394 | |
395 base::Closure fence_retired_callback = | |
396 base::Bind(&GLSurfaceOzoneSurfaceless::FenceRetired, | |
397 weak_factory_.GetWeakPtr(), fence, frame); | |
398 | |
399 base::WorkerPool::PostTaskAndReply(FROM_HERE, fence_wait_task, | |
400 fence_retired_callback, false); | |
401 return; // Defer frame submission until fence signals. | |
402 } | |
403 | |
404 frame->ready = true; | |
405 SubmitFrame(); | |
406 } | |
407 | |
408 void GLSurfaceOzoneSurfaceless::PostSubBufferAsync( | |
409 int x, | |
410 int y, | |
411 int width, | |
412 int height, | |
413 const SwapCompletionCallback& callback) { | |
414 // The actual sub buffer handling is handled at higher layers. | |
415 SwapBuffersAsync(callback); | |
416 } | |
417 | |
418 EGLConfig GLSurfaceOzoneSurfaceless::GetConfig() { | |
419 if (!config_) { | |
420 ui::EglConfigCallbacks callbacks = GetEglConfigCallbacks(GetDisplay()); | |
421 config_ = ozone_surface_->GetEGLSurfaceConfig(callbacks); | |
422 } | |
423 if (config_) | |
424 return config_; | |
425 return SurfacelessEGL::GetConfig(); | |
426 } | |
427 | |
428 GLSurfaceOzoneSurfaceless::~GLSurfaceOzoneSurfaceless() { | |
429 Destroy(); // The EGL surface must be destroyed before SurfaceOzone. | |
430 } | |
431 | |
432 void GLSurfaceOzoneSurfaceless::SubmitFrame() { | |
433 DCHECK(!unsubmitted_frames_.empty()); | |
434 | |
435 if (unsubmitted_frames_.front()->ready && !swap_buffers_pending_) { | |
436 std::unique_ptr<PendingFrame> frame(unsubmitted_frames_.front()); | |
437 unsubmitted_frames_.weak_erase(unsubmitted_frames_.begin()); | |
438 swap_buffers_pending_ = true; | |
439 | |
440 if (!frame->ScheduleOverlayPlanes(widget_)) { | |
441 // |callback| is a wrapper for SwapCompleted(). Call it to properly | |
442 // propagate the failed state. | |
443 frame->callback.Run(gfx::SwapResult::SWAP_FAILED); | |
444 return; | |
445 } | |
446 | |
447 if (ozone_surface_->IsUniversalDisplayLinkDevice()) | |
448 glFinish(); | |
449 | |
450 ozone_surface_->OnSwapBuffersAsync(frame->callback); | |
451 } | |
452 } | |
453 | |
454 EGLSyncKHR GLSurfaceOzoneSurfaceless::InsertFence(bool implicit) { | |
455 const EGLint attrib_list[] = {EGL_SYNC_CONDITION_KHR, | |
456 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, | |
457 EGL_NONE}; | |
458 return eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, | |
459 implicit ? attrib_list : NULL); | |
460 } | |
461 | |
462 void GLSurfaceOzoneSurfaceless::FenceRetired(EGLSyncKHR fence, | |
463 PendingFrame* frame) { | |
464 eglDestroySyncKHR(GetDisplay(), fence); | |
465 frame->ready = true; | |
466 SubmitFrame(); | |
467 } | |
468 | |
469 void GLSurfaceOzoneSurfaceless::SwapCompleted( | |
470 const SwapCompletionCallback& callback, | |
471 gfx::SwapResult result) { | |
472 callback.Run(result); | |
473 swap_buffers_pending_ = false; | |
474 if (result == gfx::SwapResult::SWAP_FAILED) { | |
475 last_swap_buffers_result_ = false; | |
476 return; | |
477 } | |
478 | |
479 SubmitFrame(); | |
480 } | |
481 | |
482 // This provides surface-like semantics implemented through surfaceless. | |
483 // A framebuffer is bound automatically. | |
484 class GL_EXPORT GLSurfaceOzoneSurfacelessSurfaceImpl | |
485 : public GLSurfaceOzoneSurfaceless { | |
486 public: | |
487 GLSurfaceOzoneSurfacelessSurfaceImpl( | |
488 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, | |
489 gfx::AcceleratedWidget widget); | |
490 | |
491 // GLSurface: | |
492 unsigned int GetBackingFrameBufferObject() override; | |
493 bool OnMakeCurrent(GLContext* context) override; | |
494 bool Resize(const gfx::Size& size, | |
495 float scale_factor, | |
496 bool has_alpha) override; | |
497 bool SupportsPostSubBuffer() override; | |
498 gfx::SwapResult SwapBuffers() override; | |
499 void SwapBuffersAsync(const SwapCompletionCallback& callback) override; | |
500 void Destroy() override; | |
501 bool IsSurfaceless() const override; | |
502 | |
503 private: | |
504 ~GLSurfaceOzoneSurfacelessSurfaceImpl() override; | |
505 | |
506 void BindFramebuffer(); | |
507 bool CreatePixmaps(); | |
508 | |
509 scoped_refptr<GLContext> context_; | |
510 GLuint fbo_; | |
511 GLuint textures_[2]; | |
512 scoped_refptr<GLImage> images_[2]; | |
513 int current_surface_; | |
514 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfacelessSurfaceImpl); | |
515 }; | |
516 | |
517 GLSurfaceOzoneSurfacelessSurfaceImpl::GLSurfaceOzoneSurfacelessSurfaceImpl( | |
518 std::unique_ptr<ui::SurfaceOzoneEGL> ozone_surface, | |
519 gfx::AcceleratedWidget widget) | |
520 : GLSurfaceOzoneSurfaceless(std::move(ozone_surface), widget), | |
521 context_(nullptr), | |
522 fbo_(0), | |
523 current_surface_(0) { | |
524 for (auto& texture : textures_) | |
525 texture = 0; | |
526 } | |
527 | |
528 unsigned int | |
529 GLSurfaceOzoneSurfacelessSurfaceImpl::GetBackingFrameBufferObject() { | |
530 return fbo_; | |
531 } | |
532 | |
533 bool GLSurfaceOzoneSurfacelessSurfaceImpl::OnMakeCurrent(GLContext* context) { | |
534 DCHECK(!context_ || context == context_); | |
535 context_ = context; | |
536 if (!fbo_) { | |
537 glGenFramebuffersEXT(1, &fbo_); | |
538 if (!fbo_) | |
539 return false; | |
540 glGenTextures(arraysize(textures_), textures_); | |
541 if (!CreatePixmaps()) | |
542 return false; | |
543 } | |
544 BindFramebuffer(); | |
545 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo_); | |
546 return SurfacelessEGL::OnMakeCurrent(context); | |
547 } | |
548 | |
549 bool GLSurfaceOzoneSurfacelessSurfaceImpl::Resize(const gfx::Size& size, | |
550 float scale_factor, | |
551 bool has_alpha) { | |
552 if (size == GetSize()) | |
553 return true; | |
554 // Alpha value isn't actually used in allocating buffers yet, so always use | |
555 // true instead. | |
556 return GLSurfaceOzoneSurfaceless::Resize(size, scale_factor, true) && | |
557 CreatePixmaps(); | |
558 } | |
559 | |
560 bool GLSurfaceOzoneSurfacelessSurfaceImpl::SupportsPostSubBuffer() { | |
561 return false; | |
562 } | |
563 | |
564 gfx::SwapResult GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffers() { | |
565 if (!images_[current_surface_]->ScheduleOverlayPlane( | |
566 widget_, 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE, | |
567 gfx::Rect(GetSize()), gfx::RectF(1, 1))) | |
568 return gfx::SwapResult::SWAP_FAILED; | |
569 gfx::SwapResult result = GLSurfaceOzoneSurfaceless::SwapBuffers(); | |
570 if (result != gfx::SwapResult::SWAP_ACK) | |
571 return result; | |
572 current_surface_ ^= 1; | |
573 BindFramebuffer(); | |
574 return gfx::SwapResult::SWAP_ACK; | |
575 } | |
576 | |
577 void GLSurfaceOzoneSurfacelessSurfaceImpl::SwapBuffersAsync( | |
578 const SwapCompletionCallback& callback) { | |
579 if (!images_[current_surface_]->ScheduleOverlayPlane( | |
580 widget_, 0, gfx::OverlayTransform::OVERLAY_TRANSFORM_NONE, | |
581 gfx::Rect(GetSize()), gfx::RectF(1, 1))) { | |
582 callback.Run(gfx::SwapResult::SWAP_FAILED); | |
583 return; | |
584 } | |
585 GLSurfaceOzoneSurfaceless::SwapBuffersAsync(callback); | |
586 current_surface_ ^= 1; | |
587 BindFramebuffer(); | |
588 } | |
589 | |
590 void GLSurfaceOzoneSurfacelessSurfaceImpl::Destroy() { | |
591 if (!context_) | |
592 return; | |
593 scoped_refptr<GLContext> previous_context = GLContext::GetCurrent(); | |
594 scoped_refptr<GLSurface> previous_surface; | |
595 | |
596 bool was_current = previous_context && previous_context->IsCurrent(nullptr) && | |
597 GLSurface::GetCurrent() == this; | |
598 if (!was_current) { | |
599 // Only take a reference to previous surface if it's not |this| | |
600 // because otherwise we can take a self reference from our own dtor. | |
601 previous_surface = GLSurface::GetCurrent(); | |
602 context_->MakeCurrent(this); | |
603 } | |
604 | |
605 glBindFramebufferEXT(GL_FRAMEBUFFER, 0); | |
606 if (fbo_) { | |
607 glDeleteTextures(arraysize(textures_), textures_); | |
608 for (auto& texture : textures_) | |
609 texture = 0; | |
610 glDeleteFramebuffersEXT(1, &fbo_); | |
611 fbo_ = 0; | |
612 } | |
613 for (auto image : images_) { | |
614 if (image) | |
615 image->Destroy(true); | |
616 } | |
617 | |
618 if (!was_current) { | |
619 if (previous_context) { | |
620 previous_context->MakeCurrent(previous_surface.get()); | |
621 } else { | |
622 context_->ReleaseCurrent(this); | |
623 } | |
624 } | |
625 } | |
626 | |
627 bool GLSurfaceOzoneSurfacelessSurfaceImpl::IsSurfaceless() const { | |
628 return false; | |
629 } | |
630 | |
631 GLSurfaceOzoneSurfacelessSurfaceImpl::~GLSurfaceOzoneSurfacelessSurfaceImpl() { | |
632 Destroy(); | |
633 } | |
634 | |
635 void GLSurfaceOzoneSurfacelessSurfaceImpl::BindFramebuffer() { | |
636 ScopedFrameBufferBinder fb(fbo_); | |
637 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | |
638 textures_[current_surface_], 0); | |
639 } | |
640 | |
641 bool GLSurfaceOzoneSurfacelessSurfaceImpl::CreatePixmaps() { | |
642 if (!fbo_) | |
643 return true; | |
644 for (size_t i = 0; i < arraysize(textures_); i++) { | |
645 scoped_refptr<ui::NativePixmap> pixmap = | |
646 ui::OzonePlatform::GetInstance() | |
647 ->GetSurfaceFactoryOzone() | |
648 ->CreateNativePixmap(widget_, GetSize(), | |
649 gfx::BufferFormat::BGRA_8888, | |
650 gfx::BufferUsage::SCANOUT); | |
651 if (!pixmap) | |
652 return false; | |
653 scoped_refptr<ui::GLImageOzoneNativePixmap> image = | |
654 new ui::GLImageOzoneNativePixmap(GetSize(), GL_BGRA_EXT); | |
655 if (!image->Initialize(pixmap.get(), gfx::BufferFormat::BGRA_8888)) | |
656 return false; | |
657 // Image must have Destroy() called before destruction. | |
658 if (images_[i]) | |
659 images_[i]->Destroy(true); | |
660 images_[i] = image; | |
661 // Bind image to texture. | |
662 ScopedTextureBinder binder(GL_TEXTURE_2D, textures_[i]); | |
663 if (!images_[i]->BindTexImage(GL_TEXTURE_2D)) | |
664 return false; | |
665 } | |
666 return true; | |
667 } | |
668 | |
669 } // namespace | 180 } // namespace |
670 | 181 |
671 scoped_refptr<GLSurface> CreateViewGLSurfaceOzone( | 182 scoped_refptr<GLSurface> CreateViewGLSurfaceOzone( |
672 gfx::AcceleratedWidget window) { | 183 gfx::AcceleratedWidget window) { |
673 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone = | 184 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone = |
674 ui::OzonePlatform::GetInstance() | 185 ui::OzonePlatform::GetInstance() |
675 ->GetSurfaceFactoryOzone() | 186 ->GetSurfaceFactoryOzone() |
676 ->CreateEGLSurfaceForWidget(window); | 187 ->CreateEGLSurfaceForWidget(window); |
677 if (!surface_ozone) | 188 if (!surface_ozone) |
678 return nullptr; | 189 return nullptr; |
679 return InitializeGLSurface( | 190 return InitializeGLSurface( |
680 new GLSurfaceOzoneEGL(std::move(surface_ozone), window)); | 191 new GLSurfaceOzoneEGL(std::move(surface_ozone), window)); |
681 } | 192 } |
682 | 193 |
683 scoped_refptr<GLSurface> CreateViewGLSurfaceOzoneSurfaceless( | |
684 gfx::AcceleratedWidget window) { | |
685 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone = | |
686 ui::OzonePlatform::GetInstance() | |
687 ->GetSurfaceFactoryOzone() | |
688 ->CreateSurfacelessEGLSurfaceForWidget(window); | |
689 if (!surface_ozone) | |
690 return nullptr; | |
691 return InitializeGLSurface( | |
692 new GLSurfaceOzoneSurfaceless(std::move(surface_ozone), window)); | |
693 } | |
694 | |
695 scoped_refptr<GLSurface> CreateViewGLSurfaceOzoneSurfacelessSurfaceImpl( | |
696 gfx::AcceleratedWidget window) { | |
697 std::unique_ptr<ui::SurfaceOzoneEGL> surface_ozone = | |
698 ui::OzonePlatform::GetInstance() | |
699 ->GetSurfaceFactoryOzone() | |
700 ->CreateSurfacelessEGLSurfaceForWidget(window); | |
701 if (!surface_ozone) | |
702 return nullptr; | |
703 return InitializeGLSurface(new GLSurfaceOzoneSurfacelessSurfaceImpl( | |
704 std::move(surface_ozone), window)); | |
705 } | |
706 | |
707 } // namespace gl | 194 } // namespace gl |
OLD | NEW |