Commit d2c56852 authored by Brian Ho's avatar Brian Ho Committed by Commit Bot

viz/cros: Use fence when scheduling overlay as primary plane

Currently, enabling SkiaRenderer on Chrome OS causes the entire
screen to flicker due to partial enablement of HW overlays [1].
To remedy these synchronization issues, we need to schedule the
primary plane overlay with a valid fence.

On Android, this is accomplished via platform-specific code that
extracts a fence from a GLImage [2][3]. In this CL, we take a more
robust approach by creating the fence on OverlayRepresentation read.
The OutputPresenter can subsequently use this fence if it exists/
the SharedImage type supports it.

[1] https://chromium-review.googlesource.com/c/chromium/src/+/2342262
[2] https://source.chromium.org/chromium/chromium/src/+/master:gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc;l=75;drc=23f61cb65a94208dc2c4728e895e87d47f64a8b6
[3] https://source.chromium.org/chromium/chromium/src/+/master:ui/gl/gl_surface_egl_surface_control.cc;l=323;drc=5c860faff8acca32094b87f229b630519326372e

Bug: 1114290
Test: CrOS with SkiaRenderer doesn't flicker
Change-Id: Ie429ef6dab66fce18d6b3f37133c4bb9ecf602cd
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2404148Reviewed-by: default avatarPeng Huang <penghuang@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Reviewed-by: default avatarDaniele Castagna <dcastagna@chromium.org>
Commit-Queue: Brian Ho <hob@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809768}
parent a9160ed8
...@@ -134,8 +134,11 @@ int PresenterImageGL::present_count() const { ...@@ -134,8 +134,11 @@ int PresenterImageGL::present_count() const {
gl::GLImage* PresenterImageGL::GetGLImage( gl::GLImage* PresenterImageGL::GetGLImage(
std::unique_ptr<gfx::GpuFence>* fence) { std::unique_ptr<gfx::GpuFence>* fence) {
if (scoped_overlay_read_access_) if (scoped_overlay_read_access_) {
if (fence)
*fence = scoped_overlay_read_access_->TakeFence();
return scoped_overlay_read_access_->gl_image(); return scoped_overlay_read_access_->gl_image();
}
DCHECK(scoped_gl_read_access_); DCHECK(scoped_gl_read_access_);
...@@ -314,7 +317,8 @@ void OutputPresenterGL::SchedulePrimaryPlane( ...@@ -314,7 +317,8 @@ void OutputPresenterGL::SchedulePrimaryPlane(
std::unique_ptr<gfx::GpuFence> fence; std::unique_ptr<gfx::GpuFence> fence;
// If the submitted_image() is being scheduled, we don't new a new fence. // If the submitted_image() is being scheduled, we don't new a new fence.
auto* gl_image = reinterpret_cast<PresenterImageGL*>(image)->GetGLImage( auto* gl_image = reinterpret_cast<PresenterImageGL*>(image)->GetGLImage(
is_submitted ? nullptr : &fence); (is_submitted || !gl_surface_->SupportsPlaneGpuFences()) ? nullptr
: &fence);
// Output surface is also z-order 0. // Output surface is also z-order 0.
constexpr int kPlaneZOrder = 0; constexpr int kPlaneZOrder = 0;
...@@ -356,7 +360,7 @@ void OutputPresenterGL::ScheduleOverlays( ...@@ -356,7 +360,7 @@ void OutputPresenterGL::ScheduleOverlays(
gl_surface_->ScheduleOverlayPlane( gl_surface_->ScheduleOverlayPlane(
overlay.plane_z_order, overlay.transform, gl_image, overlay.plane_z_order, overlay.transform, gl_image,
ToNearestRect(overlay.display_rect), overlay.uv_rect, ToNearestRect(overlay.display_rect), overlay.uv_rect,
!overlay.is_opaque, nullptr /* gpu_fence */); !overlay.is_opaque, accesses[i]->TakeFence());
} }
#elif defined(OS_APPLE) #elif defined(OS_APPLE)
gl_surface_->ScheduleCALayer(ui::CARendererLayerParams( gl_surface_->ScheduleCALayer(ui::CARendererLayerParams(
......
...@@ -240,6 +240,7 @@ class SharedImageRepresentationOverlayAHB ...@@ -240,6 +240,7 @@ class SharedImageRepresentationOverlayAHB
} }
gl::GLImage* GetGLImage() override { return gl_image_; } gl::GLImage* GetGLImage() override { return gl_image_; }
std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; }
gl::GLImage* gl_image_ = nullptr; gl::GLImage* gl_image_ = nullptr;
}; };
......
...@@ -73,14 +73,20 @@ gles2::Texture* SharedImageRepresentationGLTextureImpl::GetTexture() { ...@@ -73,14 +73,20 @@ gles2::Texture* SharedImageRepresentationGLTextureImpl::GetTexture() {
} }
bool SharedImageRepresentationGLTextureImpl::BeginAccess(GLenum mode) { bool SharedImageRepresentationGLTextureImpl::BeginAccess(GLenum mode) {
DCHECK(mode_ == 0);
mode_ = mode;
if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM) if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return client_->SharedImageRepresentationGLTextureBeginAccess(); return client_->SharedImageRepresentationGLTextureBeginAccess();
return true; return true;
} }
void SharedImageRepresentationGLTextureImpl::EndAccess() { void SharedImageRepresentationGLTextureImpl::EndAccess() {
DCHECK(mode_ != 0);
GLenum current_mode = mode_;
mode_ = 0;
if (client_) if (client_)
return client_->SharedImageRepresentationGLTextureEndAccess(); return client_->SharedImageRepresentationGLTextureEndAccess(
current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -111,14 +117,20 @@ SharedImageRepresentationGLTexturePassthroughImpl::GetTexturePassthrough() { ...@@ -111,14 +117,20 @@ SharedImageRepresentationGLTexturePassthroughImpl::GetTexturePassthrough() {
bool SharedImageRepresentationGLTexturePassthroughImpl::BeginAccess( bool SharedImageRepresentationGLTexturePassthroughImpl::BeginAccess(
GLenum mode) { GLenum mode) {
DCHECK(mode_ == 0);
mode_ = mode;
if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM) if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
return client_->SharedImageRepresentationGLTextureBeginAccess(); return client_->SharedImageRepresentationGLTextureBeginAccess();
return true; return true;
} }
void SharedImageRepresentationGLTexturePassthroughImpl::EndAccess() { void SharedImageRepresentationGLTexturePassthroughImpl::EndAccess() {
DCHECK(mode_ != 0);
GLenum current_mode = mode_;
mode_ = 0;
if (client_) if (client_)
return client_->SharedImageRepresentationGLTextureEndAccess(); return client_->SharedImageRepresentationGLTextureEndAccess(
current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
...@@ -191,7 +203,7 @@ void SharedImageRepresentationSkiaImpl::EndWriteAccess( ...@@ -191,7 +203,7 @@ void SharedImageRepresentationSkiaImpl::EndWriteAccess(
write_surface_ = nullptr; write_surface_ = nullptr;
if (client_) if (client_)
client_->SharedImageRepresentationGLTextureEndAccess(); client_->SharedImageRepresentationGLTextureEndAccess(false /* readonly */);
} }
sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess( sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess(
...@@ -208,7 +220,7 @@ sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess( ...@@ -208,7 +220,7 @@ sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkiaImpl::BeginReadAccess(
void SharedImageRepresentationSkiaImpl::EndReadAccess() { void SharedImageRepresentationSkiaImpl::EndReadAccess() {
if (client_) if (client_)
client_->SharedImageRepresentationGLTextureEndAccess(); client_->SharedImageRepresentationGLTextureEndAccess(true /* readonly */);
} }
bool SharedImageRepresentationSkiaImpl::SupportsMultipleConcurrentReadAccess() { bool SharedImageRepresentationSkiaImpl::SupportsMultipleConcurrentReadAccess() {
...@@ -246,6 +258,12 @@ gl::GLImage* SharedImageRepresentationOverlayImpl::GetGLImage() { ...@@ -246,6 +258,12 @@ gl::GLImage* SharedImageRepresentationOverlayImpl::GetGLImage() {
return gl_image_.get(); return gl_image_.get();
} }
std::unique_ptr<gfx::GpuFence>
SharedImageRepresentationOverlayImpl::GetReadFence() {
auto* gl_backing = static_cast<SharedImageBackingGLImage*>(backing());
return gl_backing->GetLastWriteGpuFence();
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// SharedImageBackingGLImage // SharedImageBackingGLImage
...@@ -359,6 +377,11 @@ GLuint SharedImageBackingGLImage::GetGLServiceId() const { ...@@ -359,6 +377,11 @@ GLuint SharedImageBackingGLImage::GetGLServiceId() const {
return 0; return 0;
} }
std::unique_ptr<gfx::GpuFence>
SharedImageBackingGLImage::GetLastWriteGpuFence() {
return last_write_gl_fence_ ? last_write_gl_fence_->GetGpuFence() : nullptr;
}
scoped_refptr<gfx::NativePixmap> SharedImageBackingGLImage::GetNativePixmap() { scoped_refptr<gfx::NativePixmap> SharedImageBackingGLImage::GetNativePixmap() {
return image_->GetNativePixmap(); return image_->GetNativePixmap();
} }
...@@ -563,7 +586,8 @@ bool SharedImageBackingGLImage:: ...@@ -563,7 +586,8 @@ bool SharedImageBackingGLImage::
return BindOrCopyImageIfNeeded(); return BindOrCopyImageIfNeeded();
} }
void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() { void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess(
bool readonly) {
#if defined(OS_MAC) #if defined(OS_MAC)
// If this image could potentially be shared with Metal via WebGPU, then flush // If this image could potentially be shared with Metal via WebGPU, then flush
// the GL context to ensure Metal will see it. // the GL context to ensure Metal will see it.
...@@ -587,6 +611,14 @@ void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() { ...@@ -587,6 +611,14 @@ void SharedImageBackingGLImage::SharedImageRepresentationGLTextureEndAccess() {
image_bind_or_copy_needed_ = true; image_bind_or_copy_needed_ = true;
} }
} }
#else
// If the image will be used for an overlay, we insert a fence that can be
// used by OutputPresenter to synchronize image writes with presentation.
if (!readonly && usage() & SHARED_IMAGE_USAGE_SCANOUT &&
gl::GLFence::IsGpuFenceSupported()) {
last_write_gl_fence_ = gl::GLFence::CreateForGpuFence();
DCHECK(last_write_gl_fence_);
}
#endif #endif
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_backing.h"
#include "gpu/command_buffer/service/shared_image_backing_gl_common.h" #include "gpu/command_buffer/service/shared_image_backing_gl_common.h"
#include "gpu/gpu_gles2_export.h" #include "gpu/gpu_gles2_export.h"
#include "ui/gl/gl_fence.h"
namespace gpu { namespace gpu {
...@@ -16,7 +17,7 @@ namespace gpu { ...@@ -16,7 +17,7 @@ namespace gpu {
class SharedImageRepresentationGLTextureClient { class SharedImageRepresentationGLTextureClient {
public: public:
virtual bool SharedImageRepresentationGLTextureBeginAccess() = 0; virtual bool SharedImageRepresentationGLTextureBeginAccess() = 0;
virtual void SharedImageRepresentationGLTextureEndAccess() = 0; virtual void SharedImageRepresentationGLTextureEndAccess(bool readonly) = 0;
virtual void SharedImageRepresentationGLTextureRelease(bool have_context) = 0; virtual void SharedImageRepresentationGLTextureRelease(bool have_context) = 0;
}; };
...@@ -41,6 +42,7 @@ class SharedImageRepresentationGLTextureImpl ...@@ -41,6 +42,7 @@ class SharedImageRepresentationGLTextureImpl
SharedImageRepresentationGLTextureClient* const client_ = nullptr; SharedImageRepresentationGLTextureClient* const client_ = nullptr;
gles2::Texture* texture_; gles2::Texture* texture_;
GLenum mode_ = 0;
}; };
// Representation of a SharedImageBackingGLTexture or // Representation of a SharedImageBackingGLTexture or
...@@ -69,6 +71,7 @@ class SharedImageRepresentationGLTexturePassthroughImpl ...@@ -69,6 +71,7 @@ class SharedImageRepresentationGLTexturePassthroughImpl
SharedImageRepresentationGLTextureClient* const client_ = nullptr; SharedImageRepresentationGLTextureClient* const client_ = nullptr;
scoped_refptr<gles2::TexturePassthrough> texture_passthrough_; scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
GLenum mode_ = 0;
}; };
// Skia representation for both SharedImageBackingGLCommon. // Skia representation for both SharedImageBackingGLCommon.
...@@ -131,6 +134,7 @@ class SharedImageRepresentationOverlayImpl ...@@ -131,6 +134,7 @@ class SharedImageRepresentationOverlayImpl
bool BeginReadAccess() override; bool BeginReadAccess() override;
void EndReadAccess() override; void EndReadAccess() override;
gl::GLImage* GetGLImage() override; gl::GLImage* GetGLImage() override;
std::unique_ptr<gfx::GpuFence> GetReadFence() override;
scoped_refptr<gl::GLImage> gl_image_; scoped_refptr<gl::GLImage> gl_image_;
}; };
...@@ -163,6 +167,7 @@ class GPU_GLES2_EXPORT SharedImageBackingGLImage ...@@ -163,6 +167,7 @@ class GPU_GLES2_EXPORT SharedImageBackingGLImage
GLenum GetGLTarget() const; GLenum GetGLTarget() const;
GLuint GetGLServiceId() const; GLuint GetGLServiceId() const;
std::unique_ptr<gfx::GpuFence> GetLastWriteGpuFence();
private: private:
// SharedImageBacking: // SharedImageBacking:
...@@ -198,7 +203,7 @@ class GPU_GLES2_EXPORT SharedImageBackingGLImage ...@@ -198,7 +203,7 @@ class GPU_GLES2_EXPORT SharedImageBackingGLImage
// SharedImageRepresentationGLTextureClient: // SharedImageRepresentationGLTextureClient:
bool SharedImageRepresentationGLTextureBeginAccess() override; bool SharedImageRepresentationGLTextureBeginAccess() override;
void SharedImageRepresentationGLTextureEndAccess() override; void SharedImageRepresentationGLTextureEndAccess(bool readonly) override;
void SharedImageRepresentationGLTextureRelease(bool have_context) override; void SharedImageRepresentationGLTextureRelease(bool have_context) override;
bool IsPassthrough() const { return is_passthrough_; } bool IsPassthrough() const { return is_passthrough_; }
...@@ -228,6 +233,7 @@ class GPU_GLES2_EXPORT SharedImageBackingGLImage ...@@ -228,6 +233,7 @@ class GPU_GLES2_EXPORT SharedImageBackingGLImage
scoped_refptr<gles2::TexturePassthrough> passthrough_texture_; scoped_refptr<gles2::TexturePassthrough> passthrough_texture_;
sk_sp<SkPromiseImageTexture> cached_promise_texture_; sk_sp<SkPromiseImageTexture> cached_promise_texture_;
std::unique_ptr<gl::GLFence> last_write_gl_fence_;
base::WeakPtrFactory<SharedImageBackingGLImage> weak_factory_; base::WeakPtrFactory<SharedImageBackingGLImage> weak_factory_;
}; };
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "gpu/command_buffer/service/texture_manager.h" #include "gpu/command_buffer/service/texture_manager.h"
#include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h"
#include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/GrDirectContext.h"
#include "ui/gl/gl_fence.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
#include "base/android/scoped_hardware_buffer_fence_sync.h" #include "base/android/scoped_hardware_buffer_fence_sync.h"
...@@ -227,8 +228,15 @@ sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkia::BeginReadAccess( ...@@ -227,8 +228,15 @@ sk_sp<SkPromiseImageTexture> SharedImageRepresentationSkia::BeginReadAccess(
SharedImageRepresentationOverlay::ScopedReadAccess::ScopedReadAccess( SharedImageRepresentationOverlay::ScopedReadAccess::ScopedReadAccess(
util::PassKey<SharedImageRepresentationOverlay> pass_key, util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation, SharedImageRepresentationOverlay* representation,
gl::GLImage* gl_image) gl::GLImage* gl_image,
: ScopedAccessBase(representation), gl_image_(gl_image) {} std::unique_ptr<gfx::GpuFence> fence)
: ScopedAccessBase(representation),
gl_image_(gl_image),
fence_(std::move(fence)) {}
SharedImageRepresentationOverlay::ScopedReadAccess::~ScopedReadAccess() {
representation()->EndReadAccess();
}
std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess> std::unique_ptr<SharedImageRepresentationOverlay::ScopedReadAccess>
SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) { SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) {
...@@ -244,7 +252,7 @@ SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) { ...@@ -244,7 +252,7 @@ SharedImageRepresentationOverlay::BeginScopedReadAccess(bool needs_gl_image) {
return std::make_unique<ScopedReadAccess>( return std::make_unique<ScopedReadAccess>(
util::PassKey<SharedImageRepresentationOverlay>(), this, util::PassKey<SharedImageRepresentationOverlay>(), this,
needs_gl_image ? GetGLImage() : nullptr); needs_gl_image ? GetGLImage() : nullptr, GetReadFence());
} }
SharedImageRepresentationDawn::ScopedAccess::ScopedAccess( SharedImageRepresentationDawn::ScopedAccess::ScopedAccess(
......
...@@ -392,20 +392,22 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay ...@@ -392,20 +392,22 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay
MemoryTypeTracker* tracker) MemoryTypeTracker* tracker)
: SharedImageRepresentation(manager, backing, tracker) {} : SharedImageRepresentation(manager, backing, tracker) {}
class ScopedReadAccess class GPU_GLES2_EXPORT ScopedReadAccess
: public ScopedAccessBase<SharedImageRepresentationOverlay> { : public ScopedAccessBase<SharedImageRepresentationOverlay> {
public: public:
ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key, ScopedReadAccess(util::PassKey<SharedImageRepresentationOverlay> pass_key,
SharedImageRepresentationOverlay* representation, SharedImageRepresentationOverlay* representation,
gl::GLImage* gl_image); gl::GLImage* gl_image,
~ScopedReadAccess() { representation()->EndReadAccess(); } std::unique_ptr<gfx::GpuFence> fence);
~ScopedReadAccess();
gl::GLImage* gl_image() const { gl::GLImage* gl_image() const { return gl_image_; }
return gl_image_;
} std::unique_ptr<gfx::GpuFence> TakeFence() { return std::move(fence_); }
private: private:
gl::GLImage* gl_image_; gl::GLImage* gl_image_;
std::unique_ptr<gfx::GpuFence> fence_;
}; };
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -426,6 +428,9 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay ...@@ -426,6 +428,9 @@ class GPU_GLES2_EXPORT SharedImageRepresentationOverlay
// TODO(penghuang): Refactor it to not depend on GL. // TODO(penghuang): Refactor it to not depend on GL.
// Get the backing as GLImage for GLSurface::ScheduleOverlayPlane. // Get the backing as GLImage for GLSurface::ScheduleOverlayPlane.
virtual gl::GLImage* GetGLImage() = 0; virtual gl::GLImage* GetGLImage() = 0;
// Optionally returns a fence to synchronize writes on the SharedImage with
// overlay presentation.
virtual std::unique_ptr<gfx::GpuFence> GetReadFence() = 0;
}; };
// An interface that allows a SharedImageBacking to hold a reference to VA-API // An interface that allows a SharedImageBacking to hold a reference to VA-API
......
...@@ -150,4 +150,9 @@ gl::GLImage* SharedImageRepresentationOverlayD3D::GetGLImage() { ...@@ -150,4 +150,9 @@ gl::GLImage* SharedImageRepresentationOverlayD3D::GetGLImage() {
return static_cast<SharedImageBackingD3D*>(backing())->GetGLImage(); return static_cast<SharedImageBackingD3D*>(backing())->GetGLImage();
} }
std::unique_ptr<gfx::GpuFence>
SharedImageRepresentationOverlayD3D::GetReadFence() {
return nullptr;
}
} // namespace gpu } // namespace gpu
...@@ -81,6 +81,7 @@ class SharedImageRepresentationOverlayD3D ...@@ -81,6 +81,7 @@ class SharedImageRepresentationOverlayD3D
void EndReadAccess() override; void EndReadAccess() override;
gl::GLImage* GetGLImage() override; gl::GLImage* GetGLImage() override;
std::unique_ptr<gfx::GpuFence> GetReadFence() override;
}; };
} // namespace gpu } // namespace gpu
......
...@@ -433,6 +433,8 @@ class SharedImageRepresentationOverlayVideo ...@@ -433,6 +433,8 @@ class SharedImageRepresentationOverlayVideo
return stream_image_.get(); return stream_image_.get();
} }
std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; }
void NotifyOverlayPromotion(bool promotion, void NotifyOverlayPromotion(bool promotion,
const gfx::Rect& bounds) override { const gfx::Rect& bounds) override {
stream_image_->NotifyOverlayPromotion(promotion, bounds); stream_image_->NotifyOverlayPromotion(promotion, bounds);
......
...@@ -118,6 +118,7 @@ class TestSharedImageRepresentationOverlay ...@@ -118,6 +118,7 @@ class TestSharedImageRepresentationOverlay
bool BeginReadAccess() override { return true; } bool BeginReadAccess() override { return true; }
void EndReadAccess() override {} void EndReadAccess() override {}
gl::GLImage* GetGLImage() override { return nullptr; } gl::GLImage* GetGLImage() override { return nullptr; }
std::unique_ptr<gfx::GpuFence> GetReadFence() override { return nullptr; }
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
void NotifyOverlayPromotion(bool promotion, void NotifyOverlayPromotion(bool promotion,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment