Index: cc/output/gl_renderer.cc |
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
index e822023aed4d354856b9e80f8a87a3bff353c6fa..08ea9b98a4f22a06808ce0bc9034ab29dad27ca5 100644 |
--- a/cc/output/gl_renderer.cc |
+++ b/cc/output/gl_renderer.cc |
@@ -40,6 +40,7 @@ |
#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" |
@@ -81,6 +82,20 @@ bool NeedsIOSurfaceReadbackWorkaround() { |
#endif |
} |
+// TODO(enne): move this to SkUtils |
+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))); |
+} |
+ |
} // anonymous namespace |
scoped_ptr<GLRenderer> GLRenderer::Create(RendererClient* client, |
@@ -113,6 +128,8 @@ GLRenderer::GLRenderer(RendererClient* client, |
highp_threshold_min_(highp_threshold_min), |
on_demand_tile_raster_resource_id_(0) { |
DCHECK(context_); |
+ |
+ ReinitializeGrContext(); |
} |
bool GLRenderer::Initialize() { |
@@ -175,10 +192,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; |
@@ -236,7 +249,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; |
+ ReinitializeGrContext(); |
+} |
void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { |
// On DEBUG builds, opaque render passes are cleared to blue to easily see |
@@ -246,10 +262,16 @@ void GLRenderer::ClearFramebuffer(DrawingFrame* frame) { |
else |
GLC(context_, context_->clearColor(0, 0, 1, 1)); |
+ bool always_clear = true; |
#ifdef NDEBUG |
- if (frame->current_render_pass->has_transparent_background) |
+ always_clear = false; |
#endif |
- context_->clear(GL_COLOR_BUFFER_BIT); |
+ if (always_clear || frame->current_render_pass->has_transparent_background) { |
+ GLbitfield clear_bits = GL_COLOR_BUFFER_BIT; |
+ if (context_->getContextAttributes().stencil) |
+ clear_bits |= GL_STENCIL_BUFFER_BIT; |
+ context_->clear(clear_bits); |
+ } |
} |
void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { |
@@ -269,17 +291,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() { |
@@ -1431,8 +1444,47 @@ void GLRenderer::DrawStreamVideoQuad(const DrawingFrame* frame, |
program->vertex_shader().matrix_location()); |
} |
+void GLRenderer::DrawPictureQuadDirectToBackbuffer( |
+ const DrawingFrame* frame, |
+ const PictureDrawQuad* quad) { |
+ DCHECK(CanUseGanesh()); |
+ |
+ // TODO(enne): Only do this if we've set some state since the last time |
+ // Ganesh drew anything. |
+ gr_context_->get()->resetContext(); |
+ |
+ 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 y_flip; |
+ y_flip.Scale3d(1.0, -1.0, 1.0); |
+ |
+ gfx::Transform contents_device_transform = frame->window_matrix * y_flip * |
+ frame->projection_matrix * quad->quadTransform(); |
+ contents_device_transform.FlattenTo2d(); |
+ SkMatrix sk_device_matrix; |
+ ToSkMatrix(&sk_device_matrix, contents_device_transform); |
+ sk_canvas_->setMatrix(sk_device_matrix); |
+ |
+ quad->picture_pile->Raster(sk_canvas_.get(), |
+ quad->content_rect, |
+ quad->contents_scale); |
+ |
+ ReinitializeGLState(); |
+} |
+ |
void GLRenderer::DrawPictureQuad(const DrawingFrame* frame, |
const PictureDrawQuad* quad) { |
+ if (quad->draw_direct_to_backbuffer && CanUseGanesh()) { |
+ 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( |
@@ -2573,6 +2625,53 @@ void GLRenderer::CleanupSharedObjects() { |
ReleaseRenderPassTextures(); |
} |
+void GLRenderer::ReinitializeGrContext() { |
+ if (!CanUseGanesh()) |
+ return; |
+ |
+ if (!gr_context_) { |
+ gr_context_.reset( |
+ new webkit::gpu::GrContextForWebGraphicsContext3D(context_)); |
+ } |
+ |
+ GrBackendRenderTargetDesc desc; |
+ desc.fWidth = ViewportWidth(); |
+ desc.fHeight = ViewportHeight(); |
+ desc.fConfig = kRGBA_8888_GrPixelConfig; |
+ desc.fOrigin = kBottomLeft_GrSurfaceOrigin; |
+ desc.fSampleCnt = 1; |
+ desc.fStencilBits = 8; |
+ desc.fRenderTargetHandle = 0; |
+ |
+ SkAutoTUnref<GrSurface> surface( |
+ gr_context_->get()->wrapBackendRenderTarget(desc)); |
+ SkAutoTUnref<SkDevice> device(SkGpuDevice::Create(surface)); |
+ sk_canvas_.reset(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::CanUseGanesh() const { |
+ return context_->getContextAttributes().stencil; |
+} |
+ |
bool GLRenderer::IsContextLost() { |
return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
} |