summaryrefslogtreecommitdiffstats
path: root/cc/output
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-21 21:31:44 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-21 21:31:44 +0000
commitbec08429286ff70c2ce5514ba44c8058fc058a27 (patch)
treed3f04253d5ba58348f533386fa352203e1650b41 /cc/output
parent2fccd420c7523d8379367cc1c8a3fc962b4babe1 (diff)
downloadchromium_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.cc154
-rw-r--r--cc/output/gl_renderer.h14
-rw-r--r--cc/output/renderer_pixeltest.cc49
-rw-r--r--cc/output/software_renderer.cc20
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);
}
}