diff options
author | boliu <boliu@chromium.org> | 2016-01-08 16:07:26 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-09 00:08:42 +0000 |
commit | 0ed4f6567c1b77cea282fac1773dfbaa2ac0c939 (patch) | |
tree | 8599606df511c089ae47b7ab52fd4dafbeb0a750 | |
parent | 770a614de349b5ec5dc0c20308ff745e215e1d8c (diff) | |
download | chromium_src-0ed4f6567c1b77cea282fac1773dfbaa2ac0c939.zip chromium_src-0ed4f6567c1b77cea282fac1773dfbaa2ac0c939.tar.gz chromium_src-0ed4f6567c1b77cea282fac1773dfbaa2ac0c939.tar.bz2 |
Implement external stencil for Android WebView
Add an OutputSurface::ApplyExternalStencil method.
Android WebView implements this method on the render thread
and applies the stencil parameters read in functor, through
the command buffer client.
BUG=574570
CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel
Review URL: https://codereview.chromium.org/1564703005
Cr-Commit-Position: refs/heads/master@{#368468}
-rw-r--r-- | android_webview/browser/aw_render_thread_context_provider.cc | 2 | ||||
-rw-r--r-- | android_webview/browser/hardware_renderer.cc | 6 | ||||
-rw-r--r-- | android_webview/browser/hardware_renderer.h | 4 | ||||
-rw-r--r-- | android_webview/browser/parent_output_surface.cc | 25 | ||||
-rw-r--r-- | android_webview/browser/parent_output_surface.h | 7 | ||||
-rw-r--r-- | android_webview/browser/scoped_app_gl_state_restore.cc | 94 | ||||
-rw-r--r-- | android_webview/browser/scoped_app_gl_state_restore.h | 21 | ||||
-rw-r--r-- | android_webview/browser/shared_renderer_state.cc | 2 | ||||
-rw-r--r-- | cc/output/gl_renderer.cc | 2 | ||||
-rw-r--r-- | cc/output/output_surface.cc | 2 | ||||
-rw-r--r-- | cc/output/output_surface.h | 1 | ||||
-rw-r--r-- | cc/output/renderer_pixeltest.cc | 1 |
12 files changed, 105 insertions, 62 deletions
diff --git a/android_webview/browser/aw_render_thread_context_provider.cc b/android_webview/browser/aw_render_thread_context_provider.cc index acc6e36..27dbf714 100644 --- a/android_webview/browser/aw_render_thread_context_provider.cc +++ b/android_webview/browser/aw_render_thread_context_provider.cc @@ -53,7 +53,7 @@ AwRenderThreadContextProvider::AwRenderThreadContextProvider( blink::WebGraphicsContext3D::Attributes attributes; attributes.antialias = false; attributes.depth = false; - attributes.stencil = false; + attributes.stencil = true; attributes.shareResources = true; attributes.noAutomaticFlushes = true; gpu::gles2::ContextCreationAttribHelper attribs_for_gles2; diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc index cde6161..5688b1c 100644 --- a/android_webview/browser/hardware_renderer.cc +++ b/android_webview/browser/hardware_renderer.cc @@ -87,8 +87,8 @@ void HardwareRenderer::CommitFrame() { DCHECK(!child_frame_->frame->gl_frame_data); } -void HardwareRenderer::DrawGL(bool stencil_enabled, - AwDrawGLInfo* draw_info) { +void HardwareRenderer::DrawGL(AwDrawGLInfo* draw_info, + const ScopedAppGLStateRestore& gl_state) { TRACE_EVENT0("android_webview", "HardwareRenderer::DrawGL"); // We need to watch if the current Android context has changed and enforce @@ -211,7 +211,7 @@ void HardwareRenderer::DrawGL(bool stencil_enabled, output_surface_ = output_surface_holder.get(); display_->Initialize(std::move(output_surface_holder), nullptr); } - output_surface_->SetExternalStencilTest(stencil_enabled); + output_surface_->SetGLState(gl_state); display_->SetExternalClip(clip); display_->DrawAndSwap(); } diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h index a5c47e8..eb1ccc9 100644 --- a/android_webview/browser/hardware_renderer.h +++ b/android_webview/browser/hardware_renderer.h @@ -26,6 +26,7 @@ namespace android_webview { class AwGLSurface; class ChildFrame; class ParentOutputSurface; +class ScopedAppGLStateRestore; class HardwareRenderer : public cc::DisplayClient, public cc::SurfaceFactoryClient { @@ -33,8 +34,7 @@ class HardwareRenderer : public cc::DisplayClient, explicit HardwareRenderer(SharedRendererState* state); ~HardwareRenderer() override; - void DrawGL(bool stencil_enabled, - AwDrawGLInfo* draw_info); + void DrawGL(AwDrawGLInfo* draw_info, const ScopedAppGLStateRestore& gl_state); void CommitFrame(); void SetBackingFrameBufferObject(int framebuffer_binding_ext); diff --git a/android_webview/browser/parent_output_surface.cc b/android_webview/browser/parent_output_surface.cc index 4a777cb..e73fecf 100644 --- a/android_webview/browser/parent_output_surface.cc +++ b/android_webview/browser/parent_output_surface.cc @@ -12,6 +12,7 @@ namespace android_webview { ParentOutputSurface::ParentOutputSurface( scoped_refptr<cc::ContextProvider> context_provider) : cc::OutputSurface(context_provider) { + stencil_state_.stencil_test_enabled = false; } ParentOutputSurface::~ParentOutputSurface() { @@ -34,4 +35,28 @@ void ParentOutputSurface::SwapBuffers(cc::CompositorFrame* frame) { client_->DidSwapBuffers(); } +void ParentOutputSurface::ApplyExternalStencil() { + DCHECK(stencil_state_.stencil_test_enabled); + gpu::gles2::GLES2Interface* gl = context_provider()->ContextGL(); + gl->StencilFuncSeparate(GL_FRONT, stencil_state_.stencil_front_func, + stencil_state_.stencil_front_mask, + stencil_state_.stencil_front_ref); + gl->StencilFuncSeparate(GL_BACK, stencil_state_.stencil_back_func, + stencil_state_.stencil_back_mask, + stencil_state_.stencil_back_ref); + gl->StencilMaskSeparate(GL_FRONT, stencil_state_.stencil_front_writemask); + gl->StencilMaskSeparate(GL_BACK, stencil_state_.stencil_back_writemask); + gl->StencilOpSeparate(GL_FRONT, stencil_state_.stencil_front_fail_op, + stencil_state_.stencil_front_z_fail_op, + stencil_state_.stencil_front_z_pass_op); + gl->StencilOpSeparate(GL_BACK, stencil_state_.stencil_back_fail_op, + stencil_state_.stencil_back_z_fail_op, + stencil_state_.stencil_back_z_pass_op); +} + +void ParentOutputSurface::SetGLState(const ScopedAppGLStateRestore& gl_state) { + stencil_state_ = gl_state.stencil_state(); + SetExternalStencilTest(stencil_state_.stencil_test_enabled); +} + } // namespace android_webview diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/parent_output_surface.h index 0467f2a..f69598e 100644 --- a/android_webview/browser/parent_output_surface.h +++ b/android_webview/browser/parent_output_surface.h @@ -5,6 +5,7 @@ #ifndef ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_ #define ANDROID_WEBVIEW_BROWSER_PARENT_OUTPUT_SURFACE_H_ +#include "android_webview/browser/scoped_app_gl_state_restore.h" #include "base/macros.h" #include "cc/output/output_surface.h" @@ -22,9 +23,13 @@ class ParentOutputSurface : NON_EXPORTED_BASE(public cc::OutputSurface) { float scale_factor, bool has_alpha) override; void SwapBuffers(cc::CompositorFrame* frame) override; - using cc::OutputSurface::SetExternalStencilTest; + void ApplyExternalStencil() override; + + void SetGLState(const ScopedAppGLStateRestore& gl_state); private: + StencilState stencil_state_; + DISALLOW_COPY_AND_ASSIGN(ParentOutputSurface); }; diff --git a/android_webview/browser/scoped_app_gl_state_restore.cc b/android_webview/browser/scoped_app_gl_state_restore.cc index 0f45ca3..caa2387 100644 --- a/android_webview/browser/scoped_app_gl_state_restore.cc +++ b/android_webview/browser/scoped_app_gl_state_restore.cc @@ -72,10 +72,10 @@ namespace internal { class ScopedAppGLStateRestoreImpl { public: - ScopedAppGLStateRestoreImpl(ScopedAppGLStateRestore::CallMode mode); + explicit ScopedAppGLStateRestoreImpl(ScopedAppGLStateRestore::CallMode mode); ~ScopedAppGLStateRestoreImpl(); - bool stencil_enabled() const { return stencil_test_; } + StencilState stencil_state() const { return stencil_state_; } GLint framebuffer_binding_ext() const { return framebuffer_binding_ext_; } private: @@ -135,22 +135,7 @@ class ScopedAppGLStateRestoreImpl { GLboolean scissor_test_; GLint scissor_box_[4]; - GLboolean stencil_test_; - GLint stencil_front_func_; - GLint stencil_front_ref_; - GLint stencil_front_mask_; - GLint stencil_back_func_; - GLint stencil_back_ref_; - GLint stencil_back_mask_; - GLint stencil_clear_; - GLint stencil_front_writemask_; - GLint stencil_back_writemask_; - GLint stencil_front_fail_op_; - GLint stencil_front_z_fail_op_; - GLint stencil_front_z_pass_op_; - GLint stencil_back_fail_op_; - GLint stencil_back_z_fail_op_; - GLint stencil_back_z_pass_op_; + StencilState stencil_state_; GLint framebuffer_binding_ext_; @@ -239,22 +224,27 @@ ScopedAppGLStateRestoreImpl::ScopedAppGLStateRestoreImpl( glGetBooleanv(GL_SAMPLE_ALPHA_TO_COVERAGE, &enable_sample_alpha_to_coverage_); glGetBooleanv(GL_SAMPLE_COVERAGE, &enable_sample_coverage_); - glGetBooleanv(GL_STENCIL_TEST, &stencil_test_); - glGetIntegerv(GL_STENCIL_FUNC, &stencil_front_func_); - glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_front_mask_); - glGetIntegerv(GL_STENCIL_REF, &stencil_front_ref_); - glGetIntegerv(GL_STENCIL_BACK_FUNC, &stencil_back_func_); - glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &stencil_back_mask_); - glGetIntegerv(GL_STENCIL_BACK_REF, &stencil_back_ref_); - glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencil_clear_); - glGetIntegerv(GL_STENCIL_WRITEMASK, &stencil_front_writemask_); - glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &stencil_back_writemask_); - glGetIntegerv(GL_STENCIL_FAIL, &stencil_front_fail_op_); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &stencil_front_z_fail_op_); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &stencil_front_z_pass_op_); - glGetIntegerv(GL_STENCIL_BACK_FAIL, &stencil_back_fail_op_); - glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &stencil_back_z_fail_op_); - glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &stencil_back_z_pass_op_); + glGetBooleanv(GL_STENCIL_TEST, &stencil_state_.stencil_test_enabled); + glGetIntegerv(GL_STENCIL_FUNC, &stencil_state_.stencil_front_func); + glGetIntegerv(GL_STENCIL_VALUE_MASK, &stencil_state_.stencil_front_mask); + glGetIntegerv(GL_STENCIL_REF, &stencil_state_.stencil_front_ref); + glGetIntegerv(GL_STENCIL_BACK_FUNC, &stencil_state_.stencil_back_func); + glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &stencil_state_.stencil_back_mask); + glGetIntegerv(GL_STENCIL_BACK_REF, &stencil_state_.stencil_back_ref); + glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencil_state_.stencil_clear); + glGetIntegerv(GL_STENCIL_WRITEMASK, &stencil_state_.stencil_front_writemask); + glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, + &stencil_state_.stencil_back_writemask); + glGetIntegerv(GL_STENCIL_FAIL, &stencil_state_.stencil_front_fail_op); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, + &stencil_state_.stencil_front_z_fail_op); + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, + &stencil_state_.stencil_front_z_pass_op); + glGetIntegerv(GL_STENCIL_BACK_FAIL, &stencil_state_.stencil_back_fail_op); + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, + &stencil_state_.stencil_back_z_fail_op); + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, + &stencil_state_.stencil_back_z_pass_op); glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &framebuffer_binding_ext_); @@ -402,22 +392,22 @@ ScopedAppGLStateRestoreImpl::~ScopedAppGLStateRestoreImpl() { break; } - GLEnableDisable(GL_STENCIL_TEST, stencil_test_); - glStencilFuncSeparate( - GL_FRONT, stencil_front_func_, stencil_front_mask_, stencil_front_ref_); - glStencilFuncSeparate( - GL_BACK, stencil_back_func_, stencil_back_mask_, stencil_back_ref_); - glClearStencil(stencil_clear_); - glStencilMaskSeparate(GL_FRONT, stencil_front_writemask_); - glStencilMaskSeparate(GL_BACK, stencil_back_writemask_); - glStencilOpSeparate(GL_FRONT, - stencil_front_fail_op_, - stencil_front_z_fail_op_, - stencil_front_z_pass_op_); - glStencilOpSeparate(GL_BACK, - stencil_back_fail_op_, - stencil_back_z_fail_op_, - stencil_back_z_pass_op_); + GLEnableDisable(GL_STENCIL_TEST, stencil_state_.stencil_test_enabled); + glStencilFuncSeparate(GL_FRONT, stencil_state_.stencil_front_func, + stencil_state_.stencil_front_mask, + stencil_state_.stencil_front_ref); + glStencilFuncSeparate(GL_BACK, stencil_state_.stencil_back_func, + stencil_state_.stencil_back_mask, + stencil_state_.stencil_back_ref); + glClearStencil(stencil_state_.stencil_clear); + glStencilMaskSeparate(GL_FRONT, stencil_state_.stencil_front_writemask); + glStencilMaskSeparate(GL_BACK, stencil_state_.stencil_back_writemask); + glStencilOpSeparate(GL_FRONT, stencil_state_.stencil_front_fail_op, + stencil_state_.stencil_front_z_fail_op, + stencil_state_.stencil_front_z_pass_op); + glStencilOpSeparate(GL_BACK, stencil_state_.stencil_back_fail_op, + stencil_state_.stencil_back_z_fail_op, + stencil_state_.stencil_back_z_pass_op); // Do not leak GLError out of chromium. ClearGLErrors(true, "Chromium GLError"); @@ -431,8 +421,8 @@ ScopedAppGLStateRestore::ScopedAppGLStateRestore(CallMode mode) ScopedAppGLStateRestore::~ScopedAppGLStateRestore() {} -bool ScopedAppGLStateRestore::stencil_enabled() const { - return impl_->stencil_enabled(); +StencilState ScopedAppGLStateRestore::stencil_state() const { + return impl_->stencil_state(); } int ScopedAppGLStateRestore::framebuffer_binding_ext() const { return impl_->framebuffer_binding_ext(); diff --git a/android_webview/browser/scoped_app_gl_state_restore.h b/android_webview/browser/scoped_app_gl_state_restore.h index 7639884..f2356f7 100644 --- a/android_webview/browser/scoped_app_gl_state_restore.h +++ b/android_webview/browser/scoped_app_gl_state_restore.h @@ -17,6 +17,25 @@ namespace internal { class ScopedAppGLStateRestoreImpl; } +struct StencilState { + unsigned char stencil_test_enabled; + int stencil_front_func; + int stencil_front_ref; + int stencil_front_mask; + int stencil_back_func; + int stencil_back_ref; + int stencil_back_mask; + int stencil_clear; + int stencil_front_writemask; + int stencil_back_writemask; + int stencil_front_fail_op; + int stencil_front_z_fail_op; + int stencil_front_z_pass_op; + int stencil_back_fail_op; + int stencil_back_z_fail_op; + int stencil_back_z_pass_op; +}; + // This class is not thread safe and should only be used on the UI thread. class ScopedAppGLStateRestore { public: @@ -28,7 +47,7 @@ class ScopedAppGLStateRestore { explicit ScopedAppGLStateRestore(CallMode mode); ~ScopedAppGLStateRestore(); - bool stencil_enabled() const; + StencilState stencil_state() const; int framebuffer_binding_ext() const; private: diff --git a/android_webview/browser/shared_renderer_state.cc b/android_webview/browser/shared_renderer_state.cc index 56c55a1..018b84b 100644 --- a/android_webview/browser/shared_renderer_state.cc +++ b/android_webview/browser/shared_renderer_state.cc @@ -300,7 +300,7 @@ void SharedRendererState::DrawGL(AwDrawGLInfo* draw_info) { return; } - hardware_renderer_->DrawGL(state_restore.stencil_enabled(), draw_info); + hardware_renderer_->DrawGL(draw_info, state_restore); DeferredGpuCommandService::GetInstance()->PerformIdleWork(false); } diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 0183068..4dc802f 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -2926,8 +2926,8 @@ void GLRenderer::BindFramebufferToOutputSurface(DrawingFrame* frame) { output_surface_->BindFramebuffer(); if (output_surface_->HasExternalStencilTest()) { + output_surface_->ApplyExternalStencil(); SetStencilEnabled(true); - gl_->StencilFunc(GL_EQUAL, 1, 1); } else { SetStencilEnabled(false); } diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 13e41d3..85372ce 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -191,6 +191,8 @@ bool OutputSurface::HasExternalStencilTest() const { return external_stencil_test_enabled_; } +void OutputSurface::ApplyExternalStencil() {} + bool OutputSurface::BindToClient(OutputSurfaceClient* client) { DCHECK(client_thread_checker_.CalledOnValidThread()); DCHECK(client); diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index f135e50..0b06800 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -92,6 +92,7 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { } virtual bool HasExternalStencilTest() const; + virtual void ApplyExternalStencil(); // Obtain the 3d context or the software device associated with this output // surface. Either of these may return a null pointer, but not both. diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc index 6c5e255..f5afaea 100644 --- a/cc/output/renderer_pixeltest.cc +++ b/cc/output/renderer_pixeltest.cc @@ -1889,6 +1889,7 @@ class ExternalStencilPixelTest : public GLRendererPixelTest { device_viewport_size_.width(), device_viewport_size_.height()); gl->Clear(GL_STENCIL_BUFFER_BIT); + gl->StencilFunc(GL_EQUAL, 1, 1); } }; |