diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-21 21:31:44 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-21 21:31:44 +0000 |
commit | bec08429286ff70c2ce5514ba44c8058fc058a27 (patch) | |
tree | d3f04253d5ba58348f533386fa352203e1650b41 /cc/output | |
parent | 2fccd420c7523d8379367cc1c8a3fc962b4babe1 (diff) | |
download | chromium_src-bec08429286ff70c2ce5514ba44c8058fc058a27.zip chromium_src-bec08429286ff70c2ce5514ba44c8058fc058a27.tar.gz chromium_src-bec08429286ff70c2ce5514ba44c8058fc058a27.tar.bz2 |
Add flag for drawing layers to screen with Ganesh
The --force-direct-layer-drawing flag causes any layer that could be
drawn direct to the backbuffer to be drawn to the backbuffer using
Ganesh. This flag also requires both the --enable-threaded-compositing
flag and the --enable-impl-side-painting flag to have any effect.
This patch also turns on testing for PictureDrawQuad using Ganesh in the
cc pixeltests.
BUG=none
Review URL: https://chromiumcodereview.appspot.com/13863015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201362 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/output')
-rw-r--r-- | cc/output/gl_renderer.cc | 154 | ||||
-rw-r--r-- | cc/output/gl_renderer.h | 14 | ||||
-rw-r--r-- | cc/output/renderer_pixeltest.cc | 49 | ||||
-rw-r--r-- | cc/output/software_renderer.cc | 20 |
4 files changed, 186 insertions, 51 deletions
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index b3d51ee..b151e36 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -42,10 +42,12 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColorFilter.h" +#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/GrTexture.h" #include "third_party/skia/include/gpu/SkGpuDevice.h" #include "third_party/skia/include/gpu/SkGrTexturePixelRef.h" +#include "third_party/skia/include/gpu/gl/GrGLInterface.h" #include "ui/gfx/quad_f.h" #include "ui/gfx/rect_conversions.h" @@ -103,11 +105,17 @@ struct GLRenderer::PendingAsyncReadPixels { scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, OutputSurface* output_surface, ResourceProvider* resource_provider, - int highp_threshold_min) { + int highp_threshold_min, + bool use_skia_gpu_backend) { scoped_ptr<GLRenderer> renderer(new GLRenderer( client, output_surface, resource_provider, highp_threshold_min)); if (!renderer->Initialize()) return scoped_ptr<GLRenderer>(); + if (use_skia_gpu_backend) { + renderer->InitializeGrContext(); + DCHECK(renderer->CanUseSkiaGPUBackend()) + << "Requested Skia GPU backend, but can't use it."; + } return renderer.Pass(); } @@ -193,10 +201,6 @@ bool GLRenderer::Initialize() { is_using_bind_uniform_ = extensions.count("GL_CHROMIUM_bind_uniform_location") > 0; - // Make sure scissoring starts as disabled. - GLC(context_, context_->disable(GL_SCISSOR_TEST)); - DCHECK(!is_scissor_enabled_); - if (!InitializeSharedObjects()) return false; @@ -205,6 +209,18 @@ bool GLRenderer::Initialize() { return true; } +void GLRenderer::InitializeGrContext() { + skia::RefPtr<GrGLInterface> interface = skia::AdoptRef( + context_->createGrGLInterface()); + if (!interface) + return; + + gr_context_ = skia::AdoptRef(GrContext::Create( + kOpenGL_GrBackend, + reinterpret_cast<GrBackendContext>(interface.get()))); + ReinitializeGrCanvas(); +} + GLRenderer::~GLRenderer() { while (!pending_async_read_pixels_.empty()) { pending_async_read_pixels_.back()->finished_read_pixels_callback.Cancel(); @@ -261,7 +277,10 @@ void GLRenderer::SendManagedMemoryStats(size_t bytes_visible, void GLRenderer::ReleaseRenderPassTextures() { render_pass_textures_.clear(); } -void GLRenderer::ViewportChanged() { is_viewport_changed_ = true; } +void GLRenderer::ViewportChanged() { + is_viewport_changed_ = true; + ReinitializeGrCanvas(); +} void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { // On DEBUG builds, opaque render passes are cleared to blue to easily see @@ -271,10 +290,18 @@ void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { else GLC(context_, context_->clearColor(0, 0, 1, 1)); -#ifdef NDEBUG - if (frame->current_render_pass->has_transparent_background) + bool always_clear = false; +#ifndef NDEBUG + always_clear = true; #endif - context_->clear(GL_COLOR_BUFFER_BIT); + if (always_clear || frame->current_render_pass->has_transparent_background) { + GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; + // Only the Skia GPU backend uses the stencil buffer. No need to clear it + // otherwise. + if (CanUseSkiaGPUBackend()) + clear_bits |= GL_STENCIL_BUFFER_BIT; + context_->clear(clear_bits); + } } void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { @@ -294,17 +321,8 @@ void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { } MakeContextCurrent(); - // Bind the common vertex attributes used for drawing all the layers. - shared_geometry_->PrepareForDraw(); - GLC(context_, context_->disable(GL_DEPTH_TEST)); - GLC(context_, context_->disable(GL_CULL_FACE)); - GLC(context_, context_->colorMask(true, true, true, true)); - GLC(context_, context_->enable(GL_BLEND)); - blend_shadow_ = true; - GLC(context_, context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); - GLC(Context(), Context()->activeTexture(GL_TEXTURE0)); - program_shadow_ = 0; + ReinitializeGLState(); } void GLRenderer::DoNoOp() { @@ -1467,8 +1485,57 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame, program->vertex_shader().matrix_location()); } +void GLRenderer::DrawPictureQuadDirectToBackbuffer( + const DrawingFrame* frame, + const PictureDrawQuad* quad) { + DCHECK(CanUseSkiaGPUBackend()); + DCHECK_EQ(quad->opacity(), 1.f) << "Need to composite to a bitmap or a " + "render surface for non-1 opacity quads"; + + // TODO(enne): This should be done more lazily / efficiently. + gr_context_->resetContext(); + + // Reset the canvas matrix to identity because the clip rect is in target + // space. + SkMatrix sk_identity; + sk_identity.setIdentity(); + sk_canvas_->setMatrix(sk_identity); + + if (is_scissor_enabled_) { + sk_canvas_->clipRect(gfx::RectToSkRect(scissor_rect_), + SkRegion::kReplace_Op); + } else { + sk_canvas_->clipRect(gfx::RectToSkRect(gfx::Rect(ViewportSize())), + SkRegion::kReplace_Op); + } + + gfx::Transform contents_device_transform = frame->window_matrix * + frame->projection_matrix * quad->quadTransform(); + contents_device_transform.Translate(quad->rect.x(), + quad->rect.y()); + contents_device_transform.FlattenTo2d(); + SkMatrix sk_device_matrix; + gfx::TransformToFlattenedSkMatrix(contents_device_transform, + &sk_device_matrix); + sk_canvas_->setMatrix(sk_device_matrix); + + quad->picture_pile->RasterDirect( + sk_canvas_.get(), quad->content_rect, quad->contents_scale, NULL); + + // Flush any drawing buffers that have been deferred. + sk_canvas_->flush(); + + // TODO(enne): This should be done more lazily / efficiently. + ReinitializeGLState(); +} + void GLRenderer::DrawPictureQuad(const DrawingFrame* frame, const PictureDrawQuad* quad) { + if (quad->can_draw_direct_to_backbuffer && CanUseSkiaGPUBackend()) { + DrawPictureQuadDirectToBackbuffer(frame, quad); + return; + } + if (on_demand_tile_raster_bitmap_.width() != quad->texture_size.width() || on_demand_tile_raster_bitmap_.height() != quad->texture_size.height()) { on_demand_tile_raster_bitmap_.setConfig( @@ -1490,8 +1557,8 @@ void GLRenderer::DrawPictureQuad(const DrawingFrame* frame, SkDevice device(on_demand_tile_raster_bitmap_); SkCanvas canvas(&device); - quad->picture_pile->Raster(&canvas, quad->content_rect, quad->contents_scale, - NULL); + quad->picture_pile->RasterToBitmap(&canvas, quad->content_rect, + quad->contents_scale, NULL); resource_provider_->SetPixels( on_demand_tile_raster_resource_id_, @@ -2798,6 +2865,51 @@ void GLRenderer::CleanupSharedObjects() { ReleaseRenderPassTextures(); } +void GLRenderer::ReinitializeGrCanvas() { + if (!CanUseSkiaGPUBackend()) + return; + + GrBackendRenderTargetDesc desc; + desc.fWidth = ViewportWidth(); + desc.fHeight = ViewportHeight(); + desc.fConfig = kRGBA_8888_GrPixelConfig; + desc.fOrigin = kTopLeft_GrSurfaceOrigin; + desc.fSampleCnt = 1; + desc.fStencilBits = 8; + desc.fRenderTargetHandle = 0; + + skia::RefPtr<GrSurface> surface( + skia::AdoptRef(gr_context_->wrapBackendRenderTarget(desc))); + skia::RefPtr<SkDevice> device( + skia::AdoptRef(SkGpuDevice::Create(surface.get()))); + sk_canvas_ = skia::AdoptRef(new SkCanvas(device.get())); +} + +void GLRenderer::ReinitializeGLState() { + // Bind the common vertex attributes used for drawing all the layers. + shared_geometry_->PrepareForDraw(); + + GLC(context_, context_->disable(GL_STENCIL_TEST)); + GLC(context_, context_->disable(GL_DEPTH_TEST)); + GLC(context_, context_->disable(GL_CULL_FACE)); + GLC(context_, context_->colorMask(true, true, true, true)); + GLC(context_, context_->enable(GL_BLEND)); + blend_shadow_ = true; + GLC(context_, context_->blendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); + GLC(context_, context_->activeTexture(GL_TEXTURE0)); + program_shadow_ = 0; + + // Make sure scissoring starts as disabled. + is_scissor_enabled_ = false; + GLC(context_, context_->disable(GL_SCISSOR_TEST)); +} + +bool GLRenderer::CanUseSkiaGPUBackend() const { + // The Skia GPU backend requires a stencil buffer. See ReinitializeGrCanvas + // implementation. + return gr_context_ && context_->getContextAttributes().stencil; +} + bool GLRenderer::IsContextLost() { return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); } diff --git a/cc/output/gl_renderer.h b/cc/output/gl_renderer.h index c83169d..b81ae04 100644 --- a/cc/output/gl_renderer.h +++ b/cc/output/gl_renderer.h @@ -45,7 +45,8 @@ class CC_EXPORT GLRenderer static scoped_ptr<GLRenderer> Create(RendererClient* client, OutputSurface* output_surface, ResourceProvider* resource_provider, - int highp_threshold_min); + int highp_threshold_min, + bool use_skia_gpu_backend); virtual ~GLRenderer(); @@ -77,6 +78,8 @@ class CC_EXPORT GLRenderer const char* file, int line); + bool CanUseSkiaGPUBackend() const; + protected: GLRenderer(RendererClient* client, OutputSurface* output_surface, @@ -85,6 +88,7 @@ class CC_EXPORT GLRenderer bool IsBackbufferDiscarded() const { return is_backbuffer_discarded_; } bool Initialize(); + void InitializeGrContext(); const gfx::QuadF& SharedGeometryQuad() const { return shared_geometry_quad_; } const GeometryBinding* SharedGeometry() const { @@ -151,6 +155,8 @@ class CC_EXPORT GLRenderer const YUVVideoDrawQuad* quad); void DrawPictureQuad(const DrawingFrame* frame, const PictureDrawQuad* quad); + void DrawPictureQuadDirectToBackbuffer(const DrawingFrame* frame, + const PictureDrawQuad* quad); void SetShaderOpacity(float opacity, int alpha_location); void SetShaderQuadF(const gfx::QuadF& quad, int quad_location); @@ -206,6 +212,9 @@ class CC_EXPORT GLRenderer const CopyRenderPassCallback& callback, bool success); + void ReinitializeGrCanvas(); + void ReinitializeGLState(); + // WebKit:: // WebGraphicsContext3D::WebGraphicsMemoryAllocationChangedCallbackCHROMIUM // implementation. @@ -392,6 +401,9 @@ class CC_EXPORT GLRenderer OutputSurface* output_surface_; WebKit::WebGraphicsContext3D* context_; + skia::RefPtr<GrContext> gr_context_; + skia::RefPtr<SkCanvas> sk_canvas_; + gfx::Rect swap_buffer_rect_; gfx::Rect scissor_rect_; bool is_viewport_changed_; diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc index 060a284..d479e5f 100644 --- a/cc/output/renderer_pixeltest.cc +++ b/cc/output/renderer_pixeltest.cc @@ -97,6 +97,16 @@ scoped_ptr<DrawQuad> CreateTestRenderPassDrawQuad( typedef ::testing::Types<GLRenderer, SoftwareRenderer> RendererTypes; TYPED_TEST_CASE(RendererPixelTest, RendererTypes); +typedef ::testing::Types<GLRenderer, + GLRendererWithSkiaGPUBackend, + SoftwareRenderer> RendererTypesWithSkiaGPUBackend; +template <typename RendererType> +class RendererPixelTestWithSkiaGPUBackend + : public RendererPixelTest<RendererType> { +}; +TYPED_TEST_CASE(RendererPixelTestWithSkiaGPUBackend, + RendererTypesWithSkiaGPUBackend); + // All pixels can be off by one, but any more than that is an error. class FuzzyPixelOffByOneComparator : public FuzzyPixelComparator { public: @@ -119,17 +129,17 @@ class FuzzyForSoftwareOnlyPixelComparator : public PixelComparator { }; template<> -bool FuzzyForSoftwareOnlyPixelComparator<GLRenderer>::Compare( +bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare( const SkBitmap& actual_bmp, const SkBitmap& expected_bmp) const { - return exact_.Compare(actual_bmp, expected_bmp); + return fuzzy_.Compare(actual_bmp, expected_bmp); } -template<> -bool FuzzyForSoftwareOnlyPixelComparator<SoftwareRenderer>::Compare( +template<typename RendererType> +bool FuzzyForSoftwareOnlyPixelComparator<RendererType>::Compare( const SkBitmap& actual_bmp, const SkBitmap& expected_bmp) const { - return fuzzy_.Compare(actual_bmp, expected_bmp); + return exact_.Compare(actual_bmp, expected_bmp); } #if !defined(OS_ANDROID) @@ -570,8 +580,10 @@ class RendererPixelTestWithBackgroundFilter gfx::Rect filter_pass_content_rect_; }; -typedef ::testing::Types<GLRenderer, SoftwareRenderer> RendererTypes; -TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter, RendererTypes); +typedef ::testing::Types<GLRenderer, SoftwareRenderer> + BackgroundFilterRendererTypes; +TYPED_TEST_CASE(RendererPixelTestWithBackgroundFilter, + BackgroundFilterRendererTypes); typedef RendererPixelTestWithBackgroundFilter<GLRenderer> GLRendererPixelTestWithBackgroundFilter; @@ -729,9 +741,10 @@ TEST_F(GLRendererPixelTest, ForceAntiAliasingOff) { ExactPixelComparator(false))); } -TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { +TYPED_TEST(RendererPixelTestWithSkiaGPUBackend, PictureDrawQuadIdentityScale) { gfx::Size pile_tile_size(1000, 1000); gfx::Rect viewport(this->device_viewport_size_); + bool use_skia_gpu_backend = this->UseSkiaGPUBackend(); // TODO(enne): the renderer should figure this out on its own. bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA); @@ -774,6 +787,7 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { contents_swizzled, viewport, 1.f, + use_skia_gpu_backend, blue_pile); pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); @@ -798,6 +812,7 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { contents_swizzled, viewport, 1.f, + use_skia_gpu_backend, green_pile); pass->quad_list.push_back(green_quad.PassAs<DrawQuad>()); @@ -810,9 +825,11 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadIdentityScale) { ExactPixelComparator(true))); } -TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { +TYPED_TEST(RendererPixelTestWithSkiaGPUBackend, + PictureDrawQuadNonIdentityScale) { gfx::Size pile_tile_size(1000, 1000); gfx::Rect viewport(this->device_viewport_size_); + bool use_skia_gpu_backend = this->UseSkiaGPUBackend(); // TODO(enne): the renderer should figure this out on its own. bool contents_swizzled = !PlatformColor::SameComponentOrder(GL_RGBA); @@ -851,6 +868,7 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { contents_swizzled, green_rect1, 1.f, + use_skia_gpu_backend, green_pile); pass->quad_list.push_back(green_quad1.PassAs<DrawQuad>()); @@ -863,6 +881,7 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { contents_swizzled, green_rect2, 1.f, + use_skia_gpu_backend, green_pile); pass->quad_list.push_back(green_quad2.PassAs<DrawQuad>()); @@ -899,10 +918,13 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFilledPile(pile_tile_size, layer_rect.size()); - pile->add_draw_rect_with_paint(layer_rect, red_paint); - SkPaint transparent_paint; - transparent_paint.setXfermodeMode(SkXfermode::kClear_Mode); - pile->add_draw_rect_with_paint(union_layer_rect, transparent_paint); + + Region outside(layer_rect); + outside.Subtract(gfx::ToEnclosingRect(union_layer_rect)); + for (Region::Iterator iter(outside); iter.has_rect(); iter.next()) { + pile->add_draw_rect_with_paint(iter.rect(), red_paint); + } + SkPaint blue_paint; blue_paint.setColor(SK_ColorBLUE); pile->add_draw_rect_with_paint(blue_layer_rect1, blue_paint); @@ -931,6 +953,7 @@ TYPED_TEST(RendererPixelTest, PictureDrawQuadNonIdentityScale) { contents_swizzled, content_union_rect, contents_scale, + use_skia_gpu_backend, pile); pass->quad_list.push_back(blue_quad.PassAs<DrawQuad>()); diff --git a/cc/output/software_renderer.cc b/cc/output/software_renderer.cc index 7dd4a71..3906ea8 100644 --- a/cc/output/software_renderer.cc +++ b/cc/output/software_renderer.cc @@ -31,19 +31,6 @@ namespace cc { namespace { -void ToSkMatrix(SkMatrix* flattened, const gfx::Transform& m) { - // Convert from 4x4 to 3x3 by dropping the third row and column. - flattened->set(0, SkDoubleToScalar(m.matrix().getDouble(0, 0))); - flattened->set(1, SkDoubleToScalar(m.matrix().getDouble(0, 1))); - flattened->set(2, SkDoubleToScalar(m.matrix().getDouble(0, 3))); - flattened->set(3, SkDoubleToScalar(m.matrix().getDouble(1, 0))); - flattened->set(4, SkDoubleToScalar(m.matrix().getDouble(1, 1))); - flattened->set(5, SkDoubleToScalar(m.matrix().getDouble(1, 3))); - flattened->set(6, SkDoubleToScalar(m.matrix().getDouble(3, 0))); - flattened->set(7, SkDoubleToScalar(m.matrix().getDouble(3, 1))); - flattened->set(8, SkDoubleToScalar(m.matrix().getDouble(3, 3))); -} - bool IsScaleAndTranslate(const SkMatrix& matrix) { return SkScalarNearlyZero(matrix[SkMatrix::kMSkewX]) && SkScalarNearlyZero(matrix[SkMatrix::kMSkewY]) && @@ -228,7 +215,8 @@ void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, const DrawQuad* quad) { frame->window_matrix * frame->projection_matrix * quad_rect_matrix; contents_device_transform.FlattenTo2d(); SkMatrix sk_device_matrix; - ToSkMatrix(&sk_device_matrix, contents_device_transform); + gfx::TransformToFlattenedSkMatrix(contents_device_transform, + &sk_device_matrix); current_canvas_->setMatrix(sk_device_matrix); current_paint_.reset(); @@ -309,7 +297,7 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, SkDevice temp_device(temp_bitmap); SkCanvas temp_canvas(&temp_device); - quad->picture_pile->Raster( + quad->picture_pile->RasterToBitmap( &temp_canvas, quad->content_rect, quad->contents_scale, NULL); current_paint_.setFilterBitmap(true); @@ -317,7 +305,7 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, } else { TRACE_EVENT0("cc", "SoftwareRenderer::DrawPictureQuad direct from PicturePile"); - quad->picture_pile->Raster( + quad->picture_pile->RasterDirect( current_canvas_, quad->content_rect, quad->contents_scale, NULL); } } |