diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/aw_render_thread_context_provider.cc index 7385f73bd1ece7..c5a585aee0f0c3 100644 --- a/android_webview/browser/aw_render_thread_context_provider.cc +++ b/android_webview/browser/aw_render_thread_context_provider.cc @@ -75,6 +75,11 @@ AwRenderThreadContextProvider::~AwRenderThreadContextProvider() { gr_context_->releaseResourcesAndAbandonContext(); } +uint32_t AwRenderThreadContextProvider::GetCopyTextureInternalFormat() { + // The attributes used in the constructor included an alpha channel. + return GL_RGBA; +} + bool AwRenderThreadContextProvider::BindToCurrentThread() { // This is called on the thread the context will be used. DCHECK(main_thread_checker_.CalledOnValidThread()); diff --git a/android_webview/browser/aw_render_thread_context_provider.h b/android_webview/browser/aw_render_thread_context_provider.h index ef0fecf13542cc..e2e45fbdba9eb3 100644 --- a/android_webview/browser/aw_render_thread_context_provider.h +++ b/android_webview/browser/aw_render_thread_context_provider.h @@ -32,6 +32,10 @@ class AwRenderThreadContextProvider : public cc::ContextProvider { scoped_refptr surface, scoped_refptr service); + // Gives the GL internal format that should be used for calling CopyTexImage2D + // on the default framebuffer. + uint32_t GetCopyTextureInternalFormat(); + private: AwRenderThreadContextProvider( scoped_refptr surface, diff --git a/android_webview/browser/parent_output_surface.cc b/android_webview/browser/parent_output_surface.cc index 22bcaf07313610..601c487fa6b83f 100644 --- a/android_webview/browser/parent_output_surface.cc +++ b/android_webview/browser/parent_output_surface.cc @@ -4,13 +4,14 @@ #include "android_webview/browser/parent_output_surface.h" +#include "android_webview/browser/aw_render_thread_context_provider.h" #include "cc/output/output_surface_client.h" #include "gpu/command_buffer/client/gles2_interface.h" namespace android_webview { ParentOutputSurface::ParentOutputSurface( - scoped_refptr context_provider) + scoped_refptr context_provider) : cc::OutputSurface(std::move(context_provider), nullptr, nullptr) { stencil_state_.stencil_test_enabled = false; } @@ -54,6 +55,11 @@ void ParentOutputSurface::ApplyExternalStencil() { stencil_state_.stencil_back_z_pass_op); } +uint32_t ParentOutputSurface::GetFramebufferCopyTextureFormat() { + auto* gl = static_cast(context_provider()); + return gl->GetCopyTextureInternalFormat(); +} + void ParentOutputSurface::SetGLState(const ScopedAppGLStateRestore& gl_state) { stencil_state_ = gl_state.stencil_state(); SetExternalStencilTest(stencil_state_.stencil_test_enabled); diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/parent_output_surface.h index f69598e17ae41d..2b125ed0698979 100644 --- a/android_webview/browser/parent_output_surface.h +++ b/android_webview/browser/parent_output_surface.h @@ -10,11 +10,12 @@ #include "cc/output/output_surface.h" namespace android_webview { +class AwRenderThreadContextProvider; class ParentOutputSurface : NON_EXPORTED_BASE(public cc::OutputSurface) { public: explicit ParentOutputSurface( - scoped_refptr context_provider); + scoped_refptr context_provider); ~ParentOutputSurface() override; // OutputSurface overrides. @@ -24,6 +25,7 @@ class ParentOutputSurface : NON_EXPORTED_BASE(public cc::OutputSurface) { bool has_alpha) override; void SwapBuffers(cc::CompositorFrame* frame) override; void ApplyExternalStencil() override; + uint32_t GetFramebufferCopyTextureFormat() override; void SetGLState(const ScopedAppGLStateRestore& gl_state); diff --git a/blimp/client/feature/compositor/blimp_context_provider.cc b/blimp/client/feature/compositor/blimp_context_provider.cc index 07e94e8e437bca..a4699fee8df78e 100644 --- a/blimp/client/feature/compositor/blimp_context_provider.cc +++ b/blimp/client/feature/compositor/blimp_context_provider.cc @@ -124,5 +124,11 @@ void BlimpContextProvider::OnLostContext() { gr_context_->OnLostContext(); } +uint32_t BlimpContextProvider::GetCopyTextureInternalFormat() { + // The attributes used to create the context in the constructor specify + // an alpha channel. + return GL_RGBA; +} + } // namespace client } // namespace blimp diff --git a/blimp/client/feature/compositor/blimp_context_provider.h b/blimp/client/feature/compositor/blimp_context_provider.h index dbcafcd62c4763..8424fc75446a5c 100644 --- a/blimp/client/feature/compositor/blimp_context_provider.h +++ b/blimp/client/feature/compositor/blimp_context_provider.h @@ -43,6 +43,10 @@ class BlimpContextProvider : public cc::ContextProvider { void SetLostContextCallback( const LostContextCallback& lost_context_callback) override; + // Gives the GL internal format that should be used for calling CopyTexImage2D + // on the default framebuffer. + uint32_t GetCopyTextureInternalFormat(); + protected: BlimpContextProvider( gfx::AcceleratedWidget widget, diff --git a/blimp/client/feature/compositor/blimp_output_surface.cc b/blimp/client/feature/compositor/blimp_output_surface.cc index 14cf68226520f6..092b712bdd6adc 100644 --- a/blimp/client/feature/compositor/blimp_output_surface.cc +++ b/blimp/client/feature/compositor/blimp_output_surface.cc @@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" +#include "blimp/client/feature/compositor/blimp_context_provider.h" #include "cc/output/output_surface_client.h" #include "gpu/command_buffer/client/context_support.h" @@ -13,7 +14,7 @@ namespace blimp { namespace client { BlimpOutputSurface::BlimpOutputSurface( - scoped_refptr context_provider) + scoped_refptr context_provider) : cc::OutputSurface(std::move(context_provider), nullptr, nullptr) {} BlimpOutputSurface::~BlimpOutputSurface() {} @@ -25,5 +26,10 @@ void BlimpOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { cc::OutputSurface::PostSwapBuffersComplete(); } +uint32_t BlimpOutputSurface::GetFramebufferCopyTextureFormat() { + auto* gl = static_cast(context_provider()); + return gl->GetCopyTextureInternalFormat(); +} + } // namespace client } // namespace blimp diff --git a/blimp/client/feature/compositor/blimp_output_surface.h b/blimp/client/feature/compositor/blimp_output_surface.h index b8d46ddc2fa89e..4b68b092a9b6ee 100644 --- a/blimp/client/feature/compositor/blimp_output_surface.h +++ b/blimp/client/feature/compositor/blimp_output_surface.h @@ -13,16 +13,18 @@ namespace blimp { namespace client { +class BlimpContextProvider; // Minimal implementation of cc::OutputSurface. class BlimpOutputSurface : public cc::OutputSurface { public: explicit BlimpOutputSurface( - scoped_refptr context_provider); + scoped_refptr context_provider); ~BlimpOutputSurface() override; // OutputSurface implementation. void SwapBuffers(cc::CompositorFrame* frame) override; + uint32_t GetFramebufferCopyTextureFormat() override; private: DISALLOW_COPY_AND_ASSIGN(BlimpOutputSurface); diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index b8893474e9173c..096bf107b25b28 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -833,7 +833,7 @@ std::unique_ptr GLRenderer::GetBackdropTexture( { ResourceProvider::ScopedWriteLockGL lock(resource_provider_, device_background_texture->id()); - GetFramebufferTexture(lock.texture_id(), RGBA_8888, bounding_rect); + GetFramebufferTexture(lock.texture_id(), bounding_rect); } return device_background_texture; } @@ -2869,7 +2869,7 @@ void GLRenderer::GetFramebufferPixelsAsync( texture_id = gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); } - GetFramebufferTexture(texture_id, RGBA_8888, window_rect); + GetFramebufferTexture(texture_id, window_rect); const GLuint64 fence_sync = gl_->InsertFenceSyncCHROMIUM(); gl_->ShallowFlushCHROMIUM(); @@ -3009,7 +3009,6 @@ void GLRenderer::FinishedReadback(unsigned source_buffer, } void GLRenderer::GetFramebufferTexture(unsigned texture_id, - ResourceFormat texture_format, const gfx::Rect& window_rect) { DCHECK(texture_id); DCHECK_GE(window_rect.x(), 0); @@ -3017,9 +3016,19 @@ void GLRenderer::GetFramebufferTexture(unsigned texture_id, DCHECK_LE(window_rect.right(), current_surface_size_.width()); DCHECK_LE(window_rect.bottom(), current_surface_size_.height()); + // If copying a non-root renderpass then use the format of the bound + // texture. Otherwise, we use the format of the default framebuffer. + GLenum format = current_framebuffer_lock_ + ? GLCopyTextureInternalFormat(current_framebuffer_format_) + : output_surface_->GetFramebufferCopyTextureFormat(); + // Verify the format is valid for GLES2's glCopyTexImage2D. + DCHECK(format == GL_ALPHA || format == GL_LUMINANCE || + format == GL_LUMINANCE_ALPHA || format == GL_RGB || format == GL_RGBA) + << format; + gl_->BindTexture(GL_TEXTURE_2D, texture_id); - gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, GLDataFormat(texture_format), - window_rect.x(), window_rect.y(), window_rect.width(), + gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, format, window_rect.x(), + window_rect.y(), window_rect.width(), window_rect.height(), 0); gl_->BindTexture(GL_TEXTURE_2D, 0); } @@ -3049,6 +3058,7 @@ bool GLRenderer::BindFramebufferToTexture(DrawingFrame* frame, current_framebuffer_lock_ = base::WrapUnique(new ResourceProvider::ScopedWriteLockGL( resource_provider_, texture->id())); + current_framebuffer_format_ = texture->format(); unsigned texture_id = current_framebuffer_lock_->texture_id(); gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0); diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index dacc64b7c5b4ef..cfa376d0ca2c83 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -92,7 +92,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer { const gfx::Rect& rect, std::unique_ptr request); void GetFramebufferTexture(unsigned texture_id, - ResourceFormat texture_format, const gfx::Rect& device_rect); void ReleaseRenderPassTextures(); enum BoundGeometry { NO_BINDING, SHARED_BINDING, CLIPPED_BINDING }; @@ -511,6 +510,8 @@ class CC_EXPORT GLRenderer : public DirectRenderer { std::unique_ptr current_framebuffer_lock_; + // This is valid when current_framebuffer_lock_ is not null. + ResourceFormat current_framebuffer_format_; class SyncQuery; std::deque> pending_sync_queries_; diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 33c43f34ad3ad2..be83075db3ae7f 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -1392,7 +1392,7 @@ TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) { gpu::gles2::GLES2Interface* gl = output_surface->context_provider()->ContextGL(); gl->GenFramebuffers(1, &fbo); - output_surface->set_framebuffer(fbo); + output_surface->set_framebuffer(fbo, GL_RGB); renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); renderer.DrawFrame(&render_passes_in_draw_order_, 1.f, device_viewport_rect, @@ -1779,6 +1779,7 @@ class MockOutputSurface : public OutputSurface { MOCK_METHOD3(Reshape, void(const gfx::Size& size, float scale_factor, bool has_alpha)); MOCK_METHOD0(BindFramebuffer, void()); + MOCK_METHOD0(GetFramebufferCopyTextureFormat, GLenum()); MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame)); }; diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index f9ec6189966926..95a52c1edd05ec 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -132,6 +132,9 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { virtual void ForceReclaimResources() {} virtual void BindFramebuffer(); + // Gives the GL internal format that should be used for calling CopyTexImage2D + // when the framebuffer is bound via BindFramebuffer(). + virtual uint32_t GetFramebufferCopyTextureFormat() = 0; // The implementation may destroy or steal the contents of the CompositorFrame // passed in (though it will not take ownership of the CompositorFrame diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index 38285da59c19d1..fb578f143439cc 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -22,11 +22,12 @@ namespace { class TestOutputSurface : public OutputSurface { public: - explicit TestOutputSurface(scoped_refptr context_provider) + explicit TestOutputSurface( + scoped_refptr context_provider) : OutputSurface(std::move(context_provider), nullptr, nullptr) {} - TestOutputSurface(scoped_refptr context_provider, - scoped_refptr worker_context_provider) + TestOutputSurface(scoped_refptr context_provider, + scoped_refptr worker_context_provider) : OutputSurface(std::move(context_provider), std::move(worker_context_provider), nullptr) {} @@ -35,7 +36,7 @@ class TestOutputSurface : public OutputSurface { std::unique_ptr software_device) : OutputSurface(nullptr, nullptr, std::move(software_device)) {} - TestOutputSurface(scoped_refptr context_provider, + TestOutputSurface(scoped_refptr context_provider, std::unique_ptr software_device) : OutputSurface(std::move(context_provider), nullptr, @@ -45,6 +46,10 @@ class TestOutputSurface : public OutputSurface { client_->DidSwapBuffers(); client_->DidSwapBuffersComplete(); } + uint32_t GetFramebufferCopyTextureFormat() override { + // TestContextProvider has no real framebuffer, just use RGB. + return GL_RGB; + } void DidSwapBuffersForTesting() { client_->DidSwapBuffers(); } diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 2e215b9078a7aa..35140d8377e8e8 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc @@ -133,8 +133,9 @@ size_t DefaultOverlayProcessor::GetStrategyCount() { class OverlayOutputSurface : public OutputSurface { public: - explicit OverlayOutputSurface(scoped_refptr context_provider) - : OutputSurface(context_provider, nullptr, nullptr) { + explicit OverlayOutputSurface( + scoped_refptr context_provider) + : OutputSurface(std::move(context_provider), nullptr, nullptr) { surface_size_ = kDisplaySize; device_scale_factor_ = 1; is_displayed_as_overlay_plane_ = true; @@ -149,6 +150,10 @@ class OverlayOutputSurface : public OutputSurface { OutputSurface::BindFramebuffer(); bind_framebuffer_count_ += 1; } + uint32_t GetFramebufferCopyTextureFormat() override { + // TestContextProvider has no real framebuffer, just use RGB. + return GL_RGB; + } void SwapBuffers(CompositorFrame* frame) override { client_->DidSwapBuffers(); } diff --git a/cc/output/renderer_unittest.cc b/cc/output/renderer_unittest.cc index e57149f978cf63..3e91248761192a 100644 --- a/cc/output/renderer_unittest.cc +++ b/cc/output/renderer_unittest.cc @@ -21,8 +21,9 @@ class TestOutputSurface : public OutputSurface { explicit TestOutputSurface(scoped_refptr context_provider); ~TestOutputSurface() override; - // OutputSurface implementation + // OutputSurface implementation. void SwapBuffers(CompositorFrame* frame) override; + uint32_t GetFramebufferCopyTextureFormat() override { return GL_RGB; } }; TestOutputSurface::TestOutputSurface( diff --git a/cc/resources/resource_format.cc b/cc/resources/resource_format.cc index 2eae8307355c7d..9a47c7e380df9c 100644 --- a/cc/resources/resource_format.cc +++ b/cc/resources/resource_format.cc @@ -63,14 +63,39 @@ GLenum GLDataFormat(ResourceFormat format) { }; static_assert(arraysize(format_gl_data_format) == (RESOURCE_FORMAT_MAX + 1), "format_gl_data_format does not handle all cases."); - return format_gl_data_format[format]; } GLenum GLInternalFormat(ResourceFormat format) { + // In GLES2, the internal format must match the texture format. (It no longer + // is true in GLES3, however it still holds for the BGRA extension.) return GLDataFormat(format); } +GLenum GLCopyTextureInternalFormat(ResourceFormat format) { + // In GLES2, valid formats for glCopyTexImage2D are: GL_ALPHA, GL_LUMINANCE, + // GL_LUMINANCE_ALPHA, GL_RGB, or GL_RGBA. + // Extensions typically used for glTexImage2D do not also work for + // glCopyTexImage2D. For instance GL_BGRA_EXT may not be used for + // anything but gl(Sub)TexImage2D: + // https://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_format_BGRA8888.txt + DCHECK_LE(format, RESOURCE_FORMAT_MAX); + static const GLenum format_gl_data_format[] = { + GL_RGBA, // RGBA_8888 + GL_RGBA, // RGBA_4444 + GL_RGBA, // BGRA_8888 + GL_ALPHA, // ALPHA_8 + GL_LUMINANCE, // LUMINANCE_8 + GL_RGB, // RGB_565 + GL_RGB, // ETC1 + GL_LUMINANCE, // RED_8 + GL_LUMINANCE, // LUMINANCE_F16 + }; + static_assert(arraysize(format_gl_data_format) == (RESOURCE_FORMAT_MAX + 1), + "format_gl_data_format does not handle all cases."); + return format_gl_data_format[format]; +} + gfx::BufferFormat BufferFormat(ResourceFormat format) { switch (format) { case BGRA_8888: diff --git a/cc/resources/resource_format.h b/cc/resources/resource_format.h index 577076f18979a8..275053f476cca4 100644 --- a/cc/resources/resource_format.h +++ b/cc/resources/resource_format.h @@ -34,6 +34,7 @@ CC_EXPORT int BitsPerPixel(ResourceFormat format); CC_EXPORT GLenum GLDataType(ResourceFormat format); CC_EXPORT GLenum GLDataFormat(ResourceFormat format); CC_EXPORT GLenum GLInternalFormat(ResourceFormat format); +CC_EXPORT GLenum GLCopyTextureInternalFormat(ResourceFormat format); CC_EXPORT gfx::BufferFormat BufferFormat(ResourceFormat format); bool IsResourceFormatCompressed(ResourceFormat format); diff --git a/cc/surfaces/surface_display_output_surface.cc b/cc/surfaces/surface_display_output_surface.cc index b0986144932d7e..397cf2fddd2c9a 100644 --- a/cc/surfaces/surface_display_output_surface.cc +++ b/cc/surfaces/surface_display_output_surface.cc @@ -124,6 +124,17 @@ void SurfaceDisplayOutputSurface::DetachFromClient() { OutputSurface::DetachFromClient(); } +void SurfaceDisplayOutputSurface::BindFramebuffer() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); +} + +uint32_t SurfaceDisplayOutputSurface::GetFramebufferCopyTextureFormat() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); + return 0; +} + void SurfaceDisplayOutputSurface::ReturnResources( const ReturnedResourceArray& resources) { CompositorFrameAck ack; diff --git a/cc/surfaces/surface_display_output_surface.h b/cc/surfaces/surface_display_output_surface.h index 717ff1f521887c..9f0b8f2b724c6f 100644 --- a/cc/surfaces/surface_display_output_surface.h +++ b/cc/surfaces/surface_display_output_surface.h @@ -45,6 +45,8 @@ class CC_SURFACES_EXPORT SurfaceDisplayOutputSurface bool BindToClient(OutputSurfaceClient* client) override; void ForceReclaimResources() override; void DetachFromClient() override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; // SurfaceFactoryClient implementation. void ReturnResources(const ReturnedResourceArray& resources) override; diff --git a/cc/test/data/background_filter_blur_off_axis.png b/cc/test/data/background_filter_blur_off_axis.png index e74ad457a90190..9f3140ca576495 100644 Binary files a/cc/test/data/background_filter_blur_off_axis.png and b/cc/test/data/background_filter_blur_off_axis.png differ diff --git a/cc/test/data/background_filter_blur_outsets.png b/cc/test/data/background_filter_blur_outsets.png index e82c7d148b84ea..6600ea5b4c5a71 100644 Binary files a/cc/test/data/background_filter_blur_outsets.png and b/cc/test/data/background_filter_blur_outsets.png differ diff --git a/cc/test/data/background_filter_rotated_gl.png b/cc/test/data/background_filter_rotated_gl.png index e866743c897491..a0ef0bffca7993 100644 Binary files a/cc/test/data/background_filter_rotated_gl.png and b/cc/test/data/background_filter_rotated_gl.png differ diff --git a/cc/test/data/force_anti_aliasing_off.png b/cc/test/data/force_anti_aliasing_off.png index 1a2c47337f2294..d6467c8ce0c393 100644 Binary files a/cc/test/data/force_anti_aliasing_off.png and b/cc/test/data/force_anti_aliasing_off.png differ diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc index 23b2eda51bef30..3408964ff57085 100644 --- a/cc/test/fake_output_surface.cc +++ b/cc/test/fake_output_surface.cc @@ -38,13 +38,7 @@ FakeOutputSurface::FakeOutputSurface( bool delegated_rendering) : OutputSurface(std::move(context_provider), std::move(worker_context_provider), - std::move(software_device)), - client_(NULL), - num_sent_frames_(0), - has_external_stencil_test_(false), - suspended_for_recycle_(false), - framebuffer_(0), - overlay_candidate_validator_(nullptr) { + std::move(software_device)) { capabilities_.delegated_rendering = delegated_rendering; } @@ -72,11 +66,19 @@ void FakeOutputSurface::SwapBuffers(CompositorFrame* frame) { } void FakeOutputSurface::BindFramebuffer() { - if (framebuffer_) + if (framebuffer_) { context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, framebuffer_); - else + } else { OutputSurface::BindFramebuffer(); + } +} + +uint32_t FakeOutputSurface::GetFramebufferCopyTextureFormat() { + if (framebuffer_) + return framebuffer_format_; + else + return GL_RGB; } bool FakeOutputSurface::BindToClient(OutputSurfaceClient* client) { diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h index a08bf454b2b78c..7c5add8aed9906 100644 --- a/cc/test/fake_output_surface.h +++ b/cc/test/fake_output_surface.h @@ -117,8 +117,12 @@ class FakeOutputSurface : public OutputSurface { OutputSurfaceClient* client() { return client_; } bool BindToClient(OutputSurfaceClient* client) override; - void set_framebuffer(unsigned framebuffer) { framebuffer_ = framebuffer; } + void set_framebuffer(GLint framebuffer, GLenum format) { + framebuffer_ = framebuffer; + framebuffer_format_ = format; + } void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; void SetTreeActivationCallback(const base::Closure& callback); @@ -165,15 +169,16 @@ class FakeOutputSurface : public OutputSurface { std::unique_ptr software_device, bool delegated_rendering); - OutputSurfaceClient* client_; + OutputSurfaceClient* client_ = nullptr; CompositorFrame last_sent_frame_; - size_t num_sent_frames_; - bool has_external_stencil_test_; - bool suspended_for_recycle_; - unsigned framebuffer_; + size_t num_sent_frames_ = 0; + bool has_external_stencil_test_ = false; + bool suspended_for_recycle_ = false; + GLint framebuffer_ = 0; + GLenum framebuffer_format_ = 0; TransferableResourceArray resources_held_by_parent_; std::unique_ptr memory_policy_to_set_at_bind_; - OverlayCandidateValidator* overlay_candidate_validator_; + OverlayCandidateValidator* overlay_candidate_validator_ = nullptr; gfx::Rect last_swap_rect_; }; diff --git a/cc/test/pixel_test_delegating_output_surface.cc b/cc/test/pixel_test_delegating_output_surface.cc index a7ceef13160bfa..d38b19c0de604b 100644 --- a/cc/test/pixel_test_delegating_output_surface.cc +++ b/cc/test/pixel_test_delegating_output_surface.cc @@ -162,6 +162,17 @@ void PixelTestDelegatingOutputSurface::ForceReclaimResources() { } } +void PixelTestDelegatingOutputSurface::BindFramebuffer() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); +} + +uint32_t PixelTestDelegatingOutputSurface::GetFramebufferCopyTextureFormat() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); + return 0; +} + void PixelTestDelegatingOutputSurface::ReturnResources( const ReturnedResourceArray& resources) { CompositorFrameAck ack; diff --git a/cc/test/pixel_test_delegating_output_surface.h b/cc/test/pixel_test_delegating_output_surface.h index b4686461f49cae..2b4166b95c0881 100644 --- a/cc/test/pixel_test_delegating_output_surface.h +++ b/cc/test/pixel_test_delegating_output_surface.h @@ -34,6 +34,8 @@ class PixelTestDelegatingOutputSurface : public OutputSurface, void DetachFromClient() override; void SwapBuffers(CompositorFrame* frame) override; void ForceReclaimResources() override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; // SurfaceFactoryClient implementation. void ReturnResources(const ReturnedResourceArray& resources) override; diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc index b13b46d314307b..b818a0828ae230 100644 --- a/cc/test/pixel_test_output_surface.cc +++ b/cc/test/pixel_test_output_surface.cc @@ -7,6 +7,7 @@ #include #include "cc/output/output_surface_client.h" +#include "third_party/khronos/GLES2/gl2.h" #include "ui/gfx/transform.h" namespace cc { @@ -54,4 +55,11 @@ void PixelTestOutputSurface::SwapBuffers(CompositorFrame* frame) { client_->DidSwapBuffers(); } +uint32_t PixelTestOutputSurface::GetFramebufferCopyTextureFormat() { + // This format will work if the |context_provider| has an RGB or RGBA + // framebuffer. For now assume tests do not want/care about alpha in + // the root render pass. + return GL_RGB; +} + } // namespace cc diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h index b18e69fa21af4c..d083cba4fdffa7 100644 --- a/cc/test/pixel_test_output_surface.h +++ b/cc/test/pixel_test_output_surface.h @@ -22,9 +22,11 @@ class PixelTestOutputSurface : public OutputSurface { std::unique_ptr software_device); ~PixelTestOutputSurface() override; + // OutputSurface implementation. void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override; bool HasExternalStencilTest() const override; void SwapBuffers(CompositorFrame* frame) override; + uint32_t GetFramebufferCopyTextureFormat() override; void set_surface_expansion_size(const gfx::Size& surface_expansion_size) { surface_expansion_size_ = surface_expansion_size; diff --git a/cc/test/test_in_process_context_provider.cc b/cc/test/test_in_process_context_provider.cc index 51d43023c4ce03..43f8196156ed44 100644 --- a/cc/test/test_in_process_context_provider.cc +++ b/cc/test/test_in_process_context_provider.cc @@ -32,10 +32,7 @@ std::unique_ptr CreateTestInProcessContext( gpu::GLInProcessContext* shared_context) { const bool is_offscreen = true; gpu::gles2::ContextCreationAttribHelper attribs; - attribs.alpha_size = 8; - attribs.blue_size = 8; - attribs.green_size = 8; - attribs.red_size = 8; + attribs.alpha_size = -1; attribs.depth_size = 24; attribs.stencil_size = 8; attribs.samples = 0; diff --git a/cc/trees/layer_tree_host_pixeltest_filters.cc b/cc/trees/layer_tree_host_pixeltest_filters.cc index 5e974fe3530ac6..cd4d961feeaac9 100644 --- a/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -80,10 +80,10 @@ TEST_F(LayerTreeHostFiltersPixelTest, BackgroundFilterBlurOutsets) { blur->SetBackgroundFilters(filters); #if defined(OS_WIN) - // Windows has 7.6975% pixels by at most 2: crbug.com/259922 - float percentage_pixels_large_error = 7.7f; + // Windows has 5.6075% pixels by at most 2: crbug.com/259922 + float percentage_pixels_large_error = 5.7f; float percentage_pixels_small_error = 0.0f; - float average_error_allowed_in_bad_pixels = 1.f; + float average_error_allowed_in_bad_pixels = 2.f; int large_error_allowed = 2; int small_error_allowed = 0; pixel_comparator_.reset(new FuzzyPixelComparator( @@ -437,10 +437,10 @@ class ImageBackgroundFilter : public LayerTreeHostFiltersPixelTest { filter->SetBackgroundFilters(filters); #if defined(OS_WIN) - // Windows has 2.5875% pixels off by at most 2: crbug.com/225027 - float percentage_pixels_large_error = 2.6f; // 994px / (200*200) + // Windows has 3.065% pixels off by at most 2: crbug.com/225027 + float percentage_pixels_large_error = 3.1f; float percentage_pixels_small_error = 0.0f; - float average_error_allowed_in_bad_pixels = 1.f; + float average_error_allowed_in_bad_pixels = 2.f; int large_error_allowed = 2; int small_error_allowed = 0; pixel_comparator_.reset(new FuzzyPixelComparator( diff --git a/components/display_compositor/buffer_queue.cc b/components/display_compositor/buffer_queue.cc index 8649d101023ec8..be5840706a2e93 100644 --- a/components/display_compositor/buffer_queue.cc +++ b/components/display_compositor/buffer_queue.cc @@ -20,8 +20,8 @@ namespace display_compositor { BufferQueue::BufferQueue(gpu::gles2::GLES2Interface* gl, - unsigned int texture_target, - unsigned int internalformat, + uint32_t texture_target, + uint32_t internal_format, GLHelper* gl_helper, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gpu::SurfaceHandle surface_handle) @@ -29,7 +29,7 @@ BufferQueue::BufferQueue(gpu::gles2::GLES2Interface* gl, fbo_(0), allocated_count_(0), texture_target_(texture_target), - internal_format_(internalformat), + internal_format_(internal_format), gl_helper_(gl_helper), gpu_memory_buffer_manager_(gpu_memory_buffer_manager), surface_handle_(surface_handle) {} @@ -83,7 +83,7 @@ void BufferQueue::SwapBuffers(const gfx::Rect& damage) { // Copy damage from the most recently swapped buffer. In the event that // the buffer was destroyed and failed to recreate, pick from the most // recently available buffer. - unsigned int texture_id = 0; + uint32_t texture_id = 0; for (auto& surface : base::Reversed(in_flight_surfaces_)) { if (surface) { texture_id = surface->texture; @@ -219,7 +219,7 @@ std::unique_ptr BufferQueue::GetNextSurface() { return nullptr; } - unsigned int id = + uint32_t id = gl_->CreateImageCHROMIUM(buffer->AsClientBuffer(), size_.width(), size_.height(), internal_format_); if (!id) { @@ -238,8 +238,8 @@ std::unique_ptr BufferQueue::GetNextSurface() { BufferQueue::AllocatedSurface::AllocatedSurface( BufferQueue* buffer_queue, std::unique_ptr buffer, - unsigned int texture, - unsigned int image, + uint32_t texture, + uint32_t image, const gfx::Rect& rect) : buffer_queue(buffer_queue), buffer(buffer.release()), diff --git a/components/display_compositor/buffer_queue.h b/components/display_compositor/buffer_queue.h index f862b88534b44d..e0a24848e21492 100644 --- a/components/display_compositor/buffer_queue.h +++ b/components/display_compositor/buffer_queue.h @@ -41,8 +41,8 @@ class GLHelper; class DISPLAY_COMPOSITOR_EXPORT BufferQueue { public: BufferQueue(gpu::gles2::GLES2Interface* gl, - unsigned int texture_target, - unsigned int internalformat, + uint32_t texture_target, + uint32_t internal_format, GLHelper* gl_helper, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, gpu::SurfaceHandle surface_handle); @@ -57,10 +57,11 @@ class DISPLAY_COMPOSITOR_EXPORT BufferQueue { void RecreateBuffers(); - unsigned int current_texture_id() const { + uint32_t current_texture_id() const { return current_surface_ ? current_surface_->texture : 0; } - unsigned int fbo() const { return fbo_; } + uint32_t fbo() const { return fbo_; } + uint32_t internal_format() const { return internal_format_; } private: friend class BufferQueueTest; @@ -69,14 +70,14 @@ class DISPLAY_COMPOSITOR_EXPORT BufferQueue { struct DISPLAY_COMPOSITOR_EXPORT AllocatedSurface { AllocatedSurface(BufferQueue* buffer_queue, std::unique_ptr buffer, - unsigned int texture, - unsigned int image, + uint32_t texture, + uint32_t image, const gfx::Rect& rect); ~AllocatedSurface(); BufferQueue* const buffer_queue; std::unique_ptr buffer; - const unsigned int texture; - const unsigned int image; + const uint32_t texture; + const uint32_t image; gfx::Rect damage; // This is the damage for this frame from the previous. }; @@ -101,10 +102,10 @@ class DISPLAY_COMPOSITOR_EXPORT BufferQueue { gpu::gles2::GLES2Interface* const gl_; gfx::Size size_; - unsigned int fbo_; + uint32_t fbo_; size_t allocated_count_; - unsigned int texture_target_; - unsigned int internal_format_; + uint32_t texture_target_; + uint32_t internal_format_; // This surface is currently bound. This may be nullptr if no surface has // been bound, or if allocation failed at bind. std::unique_ptr current_surface_; diff --git a/components/mus/public/cpp/lib/output_surface.cc b/components/mus/public/cpp/lib/output_surface.cc index f8237d5b452f53..086e290575fbad 100644 --- a/components/mus/public/cpp/lib/output_surface.cc +++ b/components/mus/public/cpp/lib/output_surface.cc @@ -34,6 +34,17 @@ void OutputSurface::DetachFromClient() { cc::OutputSurface::DetachFromClient(); } +void OutputSurface::BindFramebuffer() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); +} + +uint32_t OutputSurface::GetFramebufferCopyTextureFormat() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); + return 0; +} + void OutputSurface::SwapBuffers(cc::CompositorFrame* frame) { // TODO(fsamuel, rjkroege): We should probably throttle compositor frames. client_->DidSwapBuffers(); diff --git a/components/mus/public/cpp/output_surface.h b/components/mus/public/cpp/output_surface.h index 4455b5ae37d9dc..c1bfe98b51b133 100644 --- a/components/mus/public/cpp/output_surface.h +++ b/components/mus/public/cpp/output_surface.h @@ -24,6 +24,8 @@ class OutputSurface : public cc::OutputSurface, public WindowSurfaceClient { void SwapBuffers(cc::CompositorFrame* frame) override; bool BindToClient(cc::OutputSurfaceClient* client) override; void DetachFromClient() override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; private: // WindowSurfaceClient implementation: diff --git a/components/mus/surfaces/direct_output_surface.cc b/components/mus/surfaces/direct_output_surface.cc index 2f2b02f5c63a98..c4c3544230604e 100644 --- a/components/mus/surfaces/direct_output_surface.cc +++ b/components/mus/surfaces/direct_output_surface.cc @@ -72,4 +72,10 @@ void DirectOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { client_->DidSwapBuffers(); } +uint32_t DirectOutputSurface::GetFramebufferCopyTextureFormat() { + // TODO(danakj): What attributes are used for the default framebuffer here? + // Can it have alpha? SurfacesContextProvider doesn't take any attributes. + return GL_RGB; +} + } // namespace mus diff --git a/components/mus/surfaces/direct_output_surface.h b/components/mus/surfaces/direct_output_surface.h index 03e71108a4af51..e8685c65d9dd51 100644 --- a/components/mus/surfaces/direct_output_surface.h +++ b/components/mus/surfaces/direct_output_surface.h @@ -31,6 +31,7 @@ class DirectOutputSurface : public cc::OutputSurface, // cc::OutputSurface implementation bool BindToClient(cc::OutputSurfaceClient* client) override; void SwapBuffers(cc::CompositorFrame* frame) override; + uint32_t GetFramebufferCopyTextureFormat() override; // SurfacesContextProviderDelegate implementation void OnVSyncParametersUpdated(const base::TimeTicks& timebase, diff --git a/components/mus/surfaces/direct_output_surface_ozone.cc b/components/mus/surfaces/direct_output_surface_ozone.cc index 48af7d772fd97f..fc302467063efb 100644 --- a/components/mus/surfaces/direct_output_surface_ozone.cc +++ b/components/mus/surfaces/direct_output_surface_ozone.cc @@ -145,6 +145,10 @@ void DirectOutputSurfaceOzone::BindFramebuffer() { buffer_queue_->BindFramebuffer(); } +uint32_t DirectOutputSurfaceOzone::GetFramebufferCopyTextureFormat() { + return buffer_queue_->internal_format(); +} + // We call this on every frame but changing the size once we've allocated // backing NativePixmapOzone instances will cause a DCHECK because // Chrome never Reshape(s) after the first one from (0,0). NB: this implies diff --git a/components/mus/surfaces/direct_output_surface_ozone.h b/components/mus/surfaces/direct_output_surface_ozone.h index 30931d3bbc42d0..25e11236239d71 100644 --- a/components/mus/surfaces/direct_output_surface_ozone.h +++ b/components/mus/surfaces/direct_output_surface_ozone.h @@ -55,6 +55,7 @@ class DirectOutputSurfaceOzone : public cc::OutputSurface { // cc::OutputSurface implementation. void SwapBuffers(cc::CompositorFrame* frame) override; void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override; bool IsDisplayedAsOverlayPlane() const override; unsigned GetOverlayTextureId() const override; diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_browser_compositor_output_surface.cc index a17c34db3ebcf0..b8e06e524ff1d9 100644 --- a/content/browser/compositor/gpu_browser_compositor_output_surface.cc +++ b/content/browser/compositor/gpu_browser_compositor_output_surface.cc @@ -65,6 +65,11 @@ bool GpuBrowserCompositorOutputSurface::BindToClient( return true; } +uint32_t GpuBrowserCompositorOutputSurface::GetFramebufferCopyTextureFormat() { + auto* gl = static_cast(context_provider()); + return gl->GetCopyTextureInternalFormat(); +} + void GpuBrowserCompositorOutputSurface::OnReflectorChanged() { if (!reflector_) { reflector_texture_.reset(); diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.h b/content/browser/compositor/gpu_browser_compositor_output_surface.h index 0e468827f199f8..d8fb372a26df5f 100644 --- a/content/browser/compositor/gpu_browser_compositor_output_surface.h +++ b/content/browser/compositor/gpu_browser_compositor_output_surface.h @@ -57,6 +57,8 @@ class GpuBrowserCompositorOutputSurface // cc::OutputSurface implementation. void SwapBuffers(cc::CompositorFrame* frame) override; bool BindToClient(cc::OutputSurfaceClient* client) override; + uint32_t GetFramebufferCopyTextureFormat() override; + gpu::CommandBufferProxyImpl* GetCommandBufferProxy(); base::CancelableCallbackBindFramebuffer(); } +GLenum GpuSurfacelessBrowserCompositorOutputSurface:: + GetFramebufferCopyTextureFormat() { + return buffer_queue_->internal_format(); +} + void GpuSurfacelessBrowserCompositorOutputSurface::Reshape( const gfx::Size& size, float scale_factor, diff --git a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h index c9dc80aa6fcfff..a091d3efe0c5c5 100644 --- a/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h +++ b/content/browser/compositor/gpu_surfaceless_browser_compositor_output_surface.h @@ -40,6 +40,7 @@ class GpuSurfacelessBrowserCompositorOutputSurface void SwapBuffers(cc::CompositorFrame* frame) override; void OnSwapBuffersComplete() override; void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override; bool IsDisplayedAsOverlayPlane() const override; unsigned GetOverlayTextureId() const override; diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc index 10b13f08beaeea..daaa970a0a8b2d 100644 --- a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc +++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc @@ -30,6 +30,8 @@ using gpu::gles2::GLES2Interface; namespace content { +static cc::ResourceFormat kFboTextureFormat = cc::RGBA_8888; + OffscreenBrowserCompositorOutputSurface:: OffscreenBrowserCompositorOutputSurface( scoped_refptr context, @@ -55,7 +57,7 @@ OffscreenBrowserCompositorOutputSurface:: void OffscreenBrowserCompositorOutputSurface::EnsureBackbuffer() { is_backbuffer_discarded_ = false; - if (!reflector_texture_.get()) { + if (!reflector_texture_) { reflector_texture_.reset(new ReflectorTexture(context_provider())); GLES2Interface* gl = context_provider_->ContextGL(); @@ -65,15 +67,15 @@ void OffscreenBrowserCompositorOutputSurface::EnsureBackbuffer() { int texture_width = std::min(max_texture_size, surface_size_.width()); int texture_height = std::min(max_texture_size, surface_size_.height()); - cc::ResourceFormat format = cc::RGBA_8888; gl->BindTexture(GL_TEXTURE_2D, reflector_texture_->texture_id()); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(format), + gl->TexImage2D(GL_TEXTURE_2D, 0, GLInternalFormat(kFboTextureFormat), texture_width, texture_height, 0, - GLDataFormat(format), GLDataType(format), nullptr); + GLDataFormat(kFboTextureFormat), + GLDataType(kFboTextureFormat), nullptr); if (!fbo_) gl->GenFramebuffers(1, &fbo_); @@ -127,6 +129,11 @@ void OffscreenBrowserCompositorOutputSurface::BindFramebuffer() { } } +GLenum +OffscreenBrowserCompositorOutputSurface::GetFramebufferCopyTextureFormat() { + return GLCopyTextureInternalFormat(kFboTextureFormat); +} + void OffscreenBrowserCompositorOutputSurface::SwapBuffers( cc::CompositorFrame* frame) { if (reflector_) { diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.h b/content/browser/compositor/offscreen_browser_compositor_output_surface.h index d9d35e9cad3bdb..1bc46645f4a555 100644 --- a/content/browser/compositor/offscreen_browser_compositor_output_surface.h +++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.h @@ -41,6 +41,7 @@ class OffscreenBrowserCompositorOutputSurface void DiscardBackbuffer() override; void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override; void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; void SwapBuffers(cc::CompositorFrame* frame) override; // BrowserCompositorOutputSurface diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc index 94ddb8f399f433..ca0535c06f6516 100644 --- a/content/browser/compositor/reflector_impl_unittest.cc +++ b/content/browser/compositor/reflector_impl_unittest.cc @@ -89,6 +89,7 @@ class TestOutputSurface : public BrowserCompositorOutputSurface { void SetFlip(bool flip) { capabilities_.flipped_output_surface = flip; } void SwapBuffers(cc::CompositorFrame* frame) override {} + uint32_t GetFramebufferCopyTextureFormat() override { return GL_RGB; } void OnReflectorChanged() override { if (!reflector_) { diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc index 14e78eb5f15240..ed1afe38bb3ec8 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.cc +++ b/content/browser/compositor/software_browser_compositor_output_surface.cc @@ -57,6 +57,18 @@ void SoftwareBrowserCompositorOutputSurface::SwapBuffers( client_->DidSwapBuffers(); } +void SoftwareBrowserCompositorOutputSurface::BindFramebuffer() { + // Not used for software surfaces. + NOTREACHED(); +} + +GLenum +SoftwareBrowserCompositorOutputSurface::GetFramebufferCopyTextureFormat() { + // Not used for software surfaces. + NOTREACHED(); + return 0; +} + void SoftwareBrowserCompositorOutputSurface::OnGpuSwapBuffersCompleted( const std::vector& latency_info, gfx::SwapResult result, diff --git a/content/browser/compositor/software_browser_compositor_output_surface.h b/content/browser/compositor/software_browser_compositor_output_surface.h index cd9d40dac67d34..026946892d20e7 100644 --- a/content/browser/compositor/software_browser_compositor_output_surface.h +++ b/content/browser/compositor/software_browser_compositor_output_surface.h @@ -31,8 +31,13 @@ class CONTENT_EXPORT SoftwareBrowserCompositorOutputSurface ~SoftwareBrowserCompositorOutputSurface() override; - private: + // OutputSurface implementation. void SwapBuffers(cc::CompositorFrame* frame) override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; + + private: + // BrowserCompositorOutputSurface implementation. void OnGpuSwapBuffersCompleted( const std::vector& latency_info, gfx::SwapResult result, diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc index a2065343d99d81..fa3b000368fcfb 100644 --- a/content/browser/renderer_host/compositor_impl_android.cc +++ b/content/browser/renderer_host/compositor_impl_android.cc @@ -202,6 +202,11 @@ class OutputSurfaceWithoutParent : public cc::OutputSurface { return overlay_candidate_validator_.get(); } + uint32_t GetFramebufferCopyTextureFormat() override { + auto* gl = static_cast(context_provider()); + return gl->GetCopyTextureInternalFormat(); + } + private: gpu::CommandBufferProxyImpl* GetCommandBufferProxy() { ContextProviderCommandBuffer* provider_command_buffer = diff --git a/content/common/gpu/client/context_provider_command_buffer.cc b/content/common/gpu/client/context_provider_command_buffer.cc index 4b24d0134b627d..857d0938615048 100644 --- a/content/common/gpu/client/context_provider_command_buffer.cc +++ b/content/common/gpu/client/context_provider_command_buffer.cc @@ -111,6 +111,15 @@ ContextProviderCommandBuffer::GetCommandBufferProxy() { return command_buffer_.get(); } +uint32_t ContextProviderCommandBuffer::GetCopyTextureInternalFormat() { + if (attributes_.alpha_size > 0) + return GL_RGBA; + DCHECK_NE(attributes_.red_size, 0); + DCHECK_NE(attributes_.green_size, 0); + DCHECK_NE(attributes_.blue_size, 0); + return GL_RGB; +} + bool ContextProviderCommandBuffer::BindToCurrentThread() { // This is called on the thread the context will be used. DCHECK(context_thread_checker_.CalledOnValidThread()); diff --git a/content/common/gpu/client/context_provider_command_buffer.h b/content/common/gpu/client/context_provider_command_buffer.h index d8f40feaac9a7f..709289e0b2ab19 100644 --- a/content/common/gpu/client/context_provider_command_buffer.h +++ b/content/common/gpu/client/context_provider_command_buffer.h @@ -62,6 +62,9 @@ class CONTENT_EXPORT ContextProviderCommandBuffer command_buffer_metrics::ContextType type); gpu::CommandBufferProxyImpl* GetCommandBufferProxy(); + // Gives the GL internal format that should be used for calling CopyTexImage2D + // on the default framebuffer. + uint32_t GetCopyTextureInternalFormat(); // cc::ContextProvider implementation. bool BindToCurrentThread() override; diff --git a/content/renderer/android/synchronous_compositor_output_surface.cc b/content/renderer/android/synchronous_compositor_output_surface.cc index dee17af0c71016..2c0d349104bcda 100644 --- a/content/renderer/android/synchronous_compositor_output_surface.cc +++ b/content/renderer/android/synchronous_compositor_output_surface.cc @@ -200,6 +200,17 @@ void SynchronousCompositorOutputSurface::Invalidate() { } } +void SynchronousCompositorOutputSurface::BindFramebuffer() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); +} + +uint32_t SynchronousCompositorOutputSurface::GetFramebufferCopyTextureFormat() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); + return 0; +} + void SynchronousCompositorOutputSurface::DemandDrawHw( const gfx::Size& surface_size, const gfx::Transform& transform, diff --git a/content/renderer/android/synchronous_compositor_output_surface.h b/content/renderer/android/synchronous_compositor_output_surface.h index 396a66d19dfc70..5d543f88075907 100644 --- a/content/renderer/android/synchronous_compositor_output_surface.h +++ b/content/renderer/android/synchronous_compositor_output_surface.h @@ -79,6 +79,8 @@ class SynchronousCompositorOutputSurface bool has_alpha) override; void SwapBuffers(cc::CompositorFrame* frame) override; void Invalidate() override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; // Partial SynchronousCompositor API implementation. void DemandDrawHw(const gfx::Size& surface_size, diff --git a/content/renderer/gpu/compositor_output_surface.cc b/content/renderer/gpu/compositor_output_surface.cc index 678eea5b2ca244..2c73f695474c8d 100644 --- a/content/renderer/gpu/compositor_output_surface.cc +++ b/content/renderer/gpu/compositor_output_surface.cc @@ -121,6 +121,17 @@ void CompositorOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { client_->DidSwapBuffers(); } +void CompositorOutputSurface::BindFramebuffer() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); +} + +uint32_t CompositorOutputSurface::GetFramebufferCopyTextureFormat() { + // This is a delegating output surface, no framebuffer/direct drawing support. + NOTREACHED(); + return 0; +} + void CompositorOutputSurface::OnMessageReceived(const IPC::Message& message) { DCHECK(client_thread_checker_.CalledOnValidThread()); if (!HasClient()) diff --git a/content/renderer/gpu/compositor_output_surface.h b/content/renderer/gpu/compositor_output_surface.h index a7b3273f2d93d9..b8b85cba731c03 100644 --- a/content/renderer/gpu/compositor_output_surface.h +++ b/content/renderer/gpu/compositor_output_surface.h @@ -58,6 +58,8 @@ class CompositorOutputSurface bool BindToClient(cc::OutputSurfaceClient* client) override; void DetachFromClient() override; void SwapBuffers(cc::CompositorFrame* frame) override; + void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; protected: uint32_t output_surface_id_; diff --git a/content/test/mailbox_output_surface.cc b/content/test/mailbox_output_surface.cc index 5edd24b2c872e7..4f4dd0d03a5164 100644 --- a/content/test/mailbox_output_surface.cc +++ b/content/test/mailbox_output_surface.cc @@ -156,6 +156,10 @@ void MailboxOutputSurface::BindFramebuffer() { current_backing_.texture_id, 0); } +uint32_t MailboxOutputSurface::GetFramebufferCopyTextureFormat() { + return GLCopyTextureInternalFormat(cc::RGBA_8888); +} + void MailboxOutputSurface::OnSwapAck(uint32_t output_surface_id, const cc::CompositorFrameAck& ack) { // Ignore message if it's a stale one coming from a different output surface diff --git a/content/test/mailbox_output_surface.h b/content/test/mailbox_output_surface.h index 743a3de708b670..88a476a1ca0b28 100644 --- a/content/test/mailbox_output_surface.h +++ b/content/test/mailbox_output_surface.h @@ -44,6 +44,7 @@ class MailboxOutputSurface : public cc::OutputSurface { void DiscardBackbuffer() override; void Reshape(const gfx::Size& size, float scale_factor, bool alpha) override; void BindFramebuffer() override; + uint32_t GetFramebufferCopyTextureFormat() override; void SwapBuffers(cc::CompositorFrame* frame) override; private: diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc index e68752f8f9c473..cc4bc292123819 100644 --- a/ui/compositor/test/in_process_context_factory.cc +++ b/ui/compositor/test/in_process_context_factory.cc @@ -50,8 +50,8 @@ class FakeReflector : public Reflector { class DirectOutputSurface : public cc::OutputSurface { public: DirectOutputSurface( - scoped_refptr context_provider, - scoped_refptr worker_context_provider) + scoped_refptr context_provider, + scoped_refptr worker_context_provider) : cc::OutputSurface(std::move(context_provider), std::move(worker_context_provider), nullptr), @@ -59,7 +59,7 @@ class DirectOutputSurface : public cc::OutputSurface { ~DirectOutputSurface() override {} - // cc::OutputSurface implementation + // cc::OutputSurface implementation. bool BindToClient(cc::OutputSurfaceClient* client) override { if (!OutputSurface::BindToClient(client)) return false; @@ -87,6 +87,10 @@ class DirectOutputSurface : public cc::OutputSurface { weak_ptr_factory_.GetWeakPtr())); client_->DidSwapBuffers(); } + uint32_t GetFramebufferCopyTextureFormat() override { + auto* gl = static_cast(context_provider()); + return gl->GetCopyTextureInternalFormat(); + } private: base::WeakPtrFactory weak_ptr_factory_; diff --git a/ui/compositor/test/in_process_context_provider.cc b/ui/compositor/test/in_process_context_provider.cc index 570044e58a550f..d2ccd5882ceb74 100644 --- a/ui/compositor/test/in_process_context_provider.cc +++ b/ui/compositor/test/in_process_context_provider.cc @@ -160,4 +160,13 @@ void InProcessContextProvider::SetLostContextCallback( // Pixel tests do not test lost context. } +uint32_t InProcessContextProvider::GetCopyTextureInternalFormat() { + if (attribs_.alpha_size > 0) + return GL_RGBA; + DCHECK_NE(attribs_.red_size, 0); + DCHECK_NE(attribs_.green_size, 0); + DCHECK_NE(attribs_.blue_size, 0); + return GL_RGB; +} + } // namespace ui diff --git a/ui/compositor/test/in_process_context_provider.h b/ui/compositor/test/in_process_context_provider.h index 7e20ed1100e732..b08c33c7baf257 100644 --- a/ui/compositor/test/in_process_context_provider.h +++ b/ui/compositor/test/in_process_context_provider.h @@ -45,7 +45,7 @@ class InProcessContextProvider : public cc::ContextProvider { gpu::ImageFactory* image_factory, InProcessContextProvider* shared_context); - // cc::ContextProvider: + // cc::ContextProvider implementation. bool BindToCurrentThread() override; void DetachFromThread() override; gpu::Capabilities ContextCapabilities() override; @@ -58,6 +58,10 @@ class InProcessContextProvider : public cc::ContextProvider { void SetLostContextCallback( const LostContextCallback& lost_context_callback) override; + // Gives the GL internal format that should be used for calling CopyTexImage2D + // on the default framebuffer. + uint32_t GetCopyTextureInternalFormat(); + private: InProcessContextProvider( const gpu::gles2::ContextCreationAttribHelper& attribs,