| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/gl/gl_surface.h" |
| |
| #include "base/check.h" |
| #include "base/command_line.h" |
| #include "base/lazy_instance.h" |
| #include "base/notreached.h" |
| #include "base/stl_util.h" |
| #include "base/threading/thread_local.h" |
| #include "base/trace_event/trace_event.h" |
| #include "ui/gfx/gpu_fence.h" |
| #include "ui/gfx/swap_result.h" |
| #include "ui/gl/gl_context.h" |
| #include "ui/gl/gl_image.h" |
| #include "ui/gl/gl_implementation.h" |
| #include "ui/gl/gl_surface_format.h" |
| #include "ui/gl/gl_switches.h" |
| |
| namespace gl { |
| |
| namespace { |
| base::LazyInstance<base::ThreadLocalPointer<GLSurface>>::Leaky |
| current_surface_ = LAZY_INSTANCE_INITIALIZER; |
| } // namespace |
| |
| GLSurface::GLSurface() = default; |
| |
| bool GLSurface::Initialize() { |
| return Initialize(GLSurfaceFormat()); |
| } |
| |
| bool GLSurface::Initialize(GLSurfaceFormat format) { |
| return true; |
| } |
| |
| void GLSurface::PrepareToDestroy(bool have_context) {} |
| |
| bool GLSurface::Resize(const gfx::Size& size, |
| float scale_factor, |
| const gfx::ColorSpace& color_space, |
| bool has_alpha) { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| bool GLSurface::Recreate() { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| bool GLSurface::DeferDraws() { |
| return false; |
| } |
| |
| bool GLSurface::SupportsSwapBuffersWithBounds() { |
| return false; |
| } |
| |
| bool GLSurface::SupportsPostSubBuffer() { |
| return false; |
| } |
| |
| bool GLSurface::SupportsCommitOverlayPlanes() { |
| return false; |
| } |
| |
| bool GLSurface::SupportsAsyncSwap() { |
| return false; |
| } |
| |
| unsigned int GLSurface::GetBackingFramebufferObject() { |
| return 0; |
| } |
| |
| void GLSurface::SwapBuffersAsync(SwapCompletionCallback completion_callback, |
| PresentationCallback presentation_callback) { |
| NOTREACHED(); |
| } |
| |
| gfx::SwapResult GLSurface::SwapBuffersWithBounds( |
| const std::vector<gfx::Rect>& rects, |
| PresentationCallback callback) { |
| return gfx::SwapResult::SWAP_FAILED; |
| } |
| |
| gfx::SwapResult GLSurface::PostSubBuffer(int x, |
| int y, |
| int width, |
| int height, |
| PresentationCallback callback) { |
| return gfx::SwapResult::SWAP_FAILED; |
| } |
| |
| void GLSurface::PostSubBufferAsync(int x, |
| int y, |
| int width, |
| int height, |
| SwapCompletionCallback completion_callback, |
| PresentationCallback presentation_callback) { |
| NOTREACHED(); |
| } |
| |
| gfx::SwapResult GLSurface::CommitOverlayPlanes(PresentationCallback callback) { |
| NOTREACHED(); |
| return gfx::SwapResult::SWAP_FAILED; |
| } |
| |
| void GLSurface::CommitOverlayPlanesAsync( |
| SwapCompletionCallback completion_callback, |
| PresentationCallback presentation_callback) { |
| NOTREACHED(); |
| } |
| |
| bool GLSurface::OnMakeCurrent(GLContext* context) { |
| return true; |
| } |
| |
| bool GLSurface::SetBackbufferAllocation(bool allocated) { |
| return true; |
| } |
| |
| void GLSurface::SetFrontbufferAllocation(bool allocated) { |
| } |
| |
| void* GLSurface::GetShareHandle() { |
| NOTIMPLEMENTED(); |
| return NULL; |
| } |
| |
| void* GLSurface::GetDisplay() { |
| NOTIMPLEMENTED(); |
| return NULL; |
| } |
| |
| void* GLSurface::GetConfig() { |
| NOTIMPLEMENTED(); |
| return NULL; |
| } |
| |
| gfx::VSyncProvider* GLSurface::GetVSyncProvider() { |
| return NULL; |
| } |
| |
| void GLSurface::SetVSyncEnabled(bool enabled) {} |
| |
| bool GLSurface::ScheduleOverlayPlane(int z_order, |
| gfx::OverlayTransform transform, |
| GLImage* image, |
| const gfx::Rect& bounds_rect, |
| const gfx::RectF& crop_rect, |
| bool enable_blend, |
| std::unique_ptr<gfx::GpuFence> gpu_fence) { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| bool GLSurface::ScheduleCALayer(const ui::CARendererLayerParams& params) { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| void GLSurface::ScheduleCALayerInUseQuery( |
| std::vector<CALayerInUseQuery> queries) { |
| NOTIMPLEMENTED(); |
| } |
| |
| bool GLSurface::ScheduleDCLayer(const ui::DCRendererLayerParams& params) { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| bool GLSurface::SetEnableDCLayers(bool enable) { |
| NOTIMPLEMENTED(); |
| return false; |
| } |
| |
| bool GLSurface::IsSurfaceless() const { |
| return false; |
| } |
| |
| gfx::SurfaceOrigin GLSurface::GetOrigin() const { |
| return gfx::SurfaceOrigin::kBottomLeft; |
| } |
| |
| bool GLSurface::BuffersFlipped() const { |
| return false; |
| } |
| |
| bool GLSurface::SupportsDCLayers() const { |
| return false; |
| } |
| |
| bool GLSurface::SupportsProtectedVideo() const { |
| return false; |
| } |
| |
| bool GLSurface::SetDrawRectangle(const gfx::Rect& rect) { |
| return false; |
| } |
| |
| gfx::Vector2d GLSurface::GetDrawOffset() const { |
| return gfx::Vector2d(); |
| } |
| |
| void GLSurface::SetRelyOnImplicitSync() { |
| // Some GLSurface derived classes might not implement this workaround while |
| // still being allocated on devices where the workaround is enabled. |
| // It is fine to ignore this call in those cases. |
| } |
| |
| void GLSurface::SetForceGlFlushOnSwapBuffers() { |
| // Some GLSurface derived classes might not implement this workaround while |
| // still being allocated on devices where the workaround is enabled. |
| // It is fine to ignore this call in those cases. |
| } |
| |
| bool GLSurface::SupportsSwapTimestamps() const { |
| return false; |
| } |
| |
| void GLSurface::SetEnableSwapTimestamps() { |
| NOTREACHED(); |
| } |
| |
| int GLSurface::GetBufferCount() const { |
| return 2; |
| } |
| |
| bool GLSurface::SupportsPlaneGpuFences() const { |
| return false; |
| } |
| |
| EGLTimestampClient* GLSurface::GetEGLTimestampClient() { |
| return nullptr; |
| } |
| |
| bool GLSurface::SupportsGpuVSync() const { |
| return false; |
| } |
| |
| void GLSurface::SetGpuVSyncEnabled(bool enabled) {} |
| |
| GLSurface* GLSurface::GetCurrent() { |
| return current_surface_.Pointer()->Get(); |
| } |
| |
| bool GLSurface::IsCurrent() { |
| return GetCurrent() == this; |
| } |
| |
| GLSurface::~GLSurface() { |
| if (GetCurrent() == this) |
| ClearCurrent(); |
| } |
| |
| void GLSurface::ClearCurrent() { |
| current_surface_.Pointer()->Set(nullptr); |
| } |
| |
| void GLSurface::SetCurrent() { |
| current_surface_.Pointer()->Set(this); |
| } |
| |
| bool GLSurface::ExtensionsContain(const char* c_extensions, const char* name) { |
| DCHECK(name); |
| if (!c_extensions) |
| return false; |
| std::string extensions(c_extensions); |
| extensions += " "; |
| |
| std::string delimited_name(name); |
| delimited_name += " "; |
| |
| return extensions.find(delimited_name) != std::string::npos; |
| } |
| |
| GLSurfaceAdapter::GLSurfaceAdapter(GLSurface* surface) : surface_(surface) {} |
| |
| void GLSurfaceAdapter::PrepareToDestroy(bool have_context) { |
| surface_->PrepareToDestroy(have_context); |
| } |
| |
| bool GLSurfaceAdapter::Initialize(GLSurfaceFormat format) { |
| return surface_->Initialize(format); |
| } |
| |
| void GLSurfaceAdapter::Destroy() { |
| surface_->Destroy(); |
| } |
| |
| bool GLSurfaceAdapter::Resize(const gfx::Size& size, |
| float scale_factor, |
| const gfx::ColorSpace& color_space, |
| bool has_alpha) { |
| return surface_->Resize(size, scale_factor, color_space, has_alpha); |
| } |
| |
| bool GLSurfaceAdapter::Recreate() { |
| return surface_->Recreate(); |
| } |
| |
| bool GLSurfaceAdapter::DeferDraws() { |
| return surface_->DeferDraws(); |
| } |
| |
| bool GLSurfaceAdapter::IsOffscreen() { |
| return surface_->IsOffscreen(); |
| } |
| |
| gfx::SwapResult GLSurfaceAdapter::SwapBuffers(PresentationCallback callback) { |
| return surface_->SwapBuffers(std::move(callback)); |
| } |
| |
| void GLSurfaceAdapter::SwapBuffersAsync( |
| SwapCompletionCallback completion_callback, |
| PresentationCallback presentation_callback) { |
| surface_->SwapBuffersAsync(std::move(completion_callback), |
| std::move(presentation_callback)); |
| } |
| |
| gfx::SwapResult GLSurfaceAdapter::SwapBuffersWithBounds( |
| const std::vector<gfx::Rect>& rects, |
| PresentationCallback callback) { |
| return surface_->SwapBuffersWithBounds(rects, std::move(callback)); |
| } |
| |
| gfx::SwapResult GLSurfaceAdapter::PostSubBuffer(int x, |
| int y, |
| int width, |
| int height, |
| PresentationCallback callback) { |
| return surface_->PostSubBuffer(x, y, width, height, std::move(callback)); |
| } |
| |
| void GLSurfaceAdapter::PostSubBufferAsync( |
| int x, |
| int y, |
| int width, |
| int height, |
| SwapCompletionCallback completion_callback, |
| PresentationCallback presentation_callback) { |
| surface_->PostSubBufferAsync(x, y, width, height, |
| std::move(completion_callback), |
| std::move(presentation_callback)); |
| } |
| |
| gfx::SwapResult GLSurfaceAdapter::CommitOverlayPlanes( |
| PresentationCallback callback) { |
| return surface_->CommitOverlayPlanes(std::move(callback)); |
| } |
| |
| void GLSurfaceAdapter::CommitOverlayPlanesAsync( |
| SwapCompletionCallback completion_callback, |
| PresentationCallback presentation_callback) { |
| surface_->CommitOverlayPlanesAsync(std::move(completion_callback), |
| std::move(presentation_callback)); |
| } |
| |
| bool GLSurfaceAdapter::SupportsSwapBuffersWithBounds() { |
| return surface_->SupportsSwapBuffersWithBounds(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsPostSubBuffer() { |
| return surface_->SupportsPostSubBuffer(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsCommitOverlayPlanes() { |
| return surface_->SupportsCommitOverlayPlanes(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsAsyncSwap() { |
| return surface_->SupportsAsyncSwap(); |
| } |
| |
| gfx::Size GLSurfaceAdapter::GetSize() { |
| return surface_->GetSize(); |
| } |
| |
| void* GLSurfaceAdapter::GetHandle() { |
| return surface_->GetHandle(); |
| } |
| |
| unsigned int GLSurfaceAdapter::GetBackingFramebufferObject() { |
| return surface_->GetBackingFramebufferObject(); |
| } |
| |
| bool GLSurfaceAdapter::OnMakeCurrent(GLContext* context) { |
| return surface_->OnMakeCurrent(context); |
| } |
| |
| bool GLSurfaceAdapter::SetBackbufferAllocation(bool allocated) { |
| return surface_->SetBackbufferAllocation(allocated); |
| } |
| |
| void GLSurfaceAdapter::SetFrontbufferAllocation(bool allocated) { |
| surface_->SetFrontbufferAllocation(allocated); |
| } |
| |
| void* GLSurfaceAdapter::GetShareHandle() { |
| return surface_->GetShareHandle(); |
| } |
| |
| void* GLSurfaceAdapter::GetDisplay() { |
| return surface_->GetDisplay(); |
| } |
| |
| void* GLSurfaceAdapter::GetConfig() { |
| return surface_->GetConfig(); |
| } |
| |
| GLSurfaceFormat GLSurfaceAdapter::GetFormat() { |
| return surface_->GetFormat(); |
| } |
| |
| gfx::VSyncProvider* GLSurfaceAdapter::GetVSyncProvider() { |
| return surface_->GetVSyncProvider(); |
| } |
| |
| void GLSurfaceAdapter::SetVSyncEnabled(bool enabled) { |
| surface_->SetVSyncEnabled(enabled); |
| } |
| |
| bool GLSurfaceAdapter::ScheduleOverlayPlane( |
| int z_order, |
| gfx::OverlayTransform transform, |
| GLImage* image, |
| const gfx::Rect& bounds_rect, |
| const gfx::RectF& crop_rect, |
| bool enable_blend, |
| std::unique_ptr<gfx::GpuFence> gpu_fence) { |
| return surface_->ScheduleOverlayPlane(z_order, transform, image, bounds_rect, |
| crop_rect, enable_blend, |
| std::move(gpu_fence)); |
| } |
| |
| bool GLSurfaceAdapter::ScheduleDCLayer( |
| const ui::DCRendererLayerParams& params) { |
| return surface_->ScheduleDCLayer(params); |
| } |
| |
| bool GLSurfaceAdapter::SetEnableDCLayers(bool enable) { |
| return surface_->SetEnableDCLayers(enable); |
| } |
| |
| bool GLSurfaceAdapter::IsSurfaceless() const { |
| return surface_->IsSurfaceless(); |
| } |
| |
| gfx::SurfaceOrigin GLSurfaceAdapter::GetOrigin() const { |
| return surface_->GetOrigin(); |
| } |
| |
| bool GLSurfaceAdapter::BuffersFlipped() const { |
| return surface_->BuffersFlipped(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsDCLayers() const { |
| return surface_->SupportsDCLayers(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsProtectedVideo() const { |
| return surface_->SupportsProtectedVideo(); |
| } |
| |
| bool GLSurfaceAdapter::SetDrawRectangle(const gfx::Rect& rect) { |
| return surface_->SetDrawRectangle(rect); |
| } |
| |
| gfx::Vector2d GLSurfaceAdapter::GetDrawOffset() const { |
| return surface_->GetDrawOffset(); |
| } |
| |
| void GLSurfaceAdapter::SetRelyOnImplicitSync() { |
| surface_->SetRelyOnImplicitSync(); |
| } |
| |
| void GLSurfaceAdapter::SetForceGlFlushOnSwapBuffers() { |
| surface_->SetForceGlFlushOnSwapBuffers(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsSwapTimestamps() const { |
| return surface_->SupportsSwapTimestamps(); |
| } |
| |
| void GLSurfaceAdapter::SetEnableSwapTimestamps() { |
| return surface_->SetEnableSwapTimestamps(); |
| } |
| |
| int GLSurfaceAdapter::GetBufferCount() const { |
| return surface_->GetBufferCount(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsPlaneGpuFences() const { |
| return surface_->SupportsPlaneGpuFences(); |
| } |
| |
| bool GLSurfaceAdapter::SupportsGpuVSync() const { |
| return surface_->SupportsGpuVSync(); |
| } |
| |
| void GLSurfaceAdapter::SetGpuVSyncEnabled(bool enabled) { |
| surface_->SetGpuVSyncEnabled(enabled); |
| } |
| |
| void GLSurfaceAdapter::SetDisplayTransform(gfx::OverlayTransform transform) { |
| return surface_->SetDisplayTransform(transform); |
| } |
| |
| void GLSurfaceAdapter::SetFrameRate(float frame_rate) { |
| surface_->SetFrameRate(frame_rate); |
| } |
| |
| void GLSurfaceAdapter::SetCurrent() { |
| surface_->SetCurrent(); |
| } |
| |
| bool GLSurfaceAdapter::IsCurrent() { |
| return surface_->IsCurrent(); |
| } |
| |
| GLSurfaceAdapter::~GLSurfaceAdapter() {} |
| |
| scoped_refptr<GLSurface> InitializeGLSurfaceWithFormat( |
| scoped_refptr<GLSurface> surface, GLSurfaceFormat format) { |
| if (!surface->Initialize(format)) |
| return nullptr; |
| return surface; |
| } |
| |
| scoped_refptr<GLSurface> InitializeGLSurface(scoped_refptr<GLSurface> surface) { |
| return InitializeGLSurfaceWithFormat(surface, GLSurfaceFormat()); |
| } |
| |
| GLSurface::CALayerInUseQuery::CALayerInUseQuery() = default; |
| GLSurface::CALayerInUseQuery::CALayerInUseQuery(const CALayerInUseQuery&) = |
| default; |
| GLSurface::CALayerInUseQuery::~CALayerInUseQuery() = default; |
| |
| } // namespace gl |