Index: cc/output/gl_renderer.cc |
diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc |
index 34807ffc151d41e1452c9007f5619e4ae0e0a2d7..112a551362c2e8d1908ff796c859450a029ec757 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,14 @@ 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_ganesh) { |
scoped_ptr<GLRenderer> renderer(new GLRenderer( |
client, output_surface, resource_provider, highp_threshold_min)); |
if (!renderer->Initialize()) |
return scoped_ptr<GLRenderer>(); |
+ if (use_ganesh) |
+ renderer->InitializeGrContext(); |
return renderer.Pass(); |
} |
@@ -193,10 +198,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 +206,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 +274,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 +287,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 (CanUseGanesh()) |
+ clear_bits |= GL_STENCIL_BUFFER_BIT; |
+ context_->clear(clear_bits); |
+ } |
} |
void GLRenderer::BeginDrawingFrame(DrawingFrame* frame) { |
@@ -294,17 +316,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() { |
@@ -1468,8 +1481,53 @@ 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_->resetContext(); |
+ |
+ if (is_scissor_enabled_) { |
+ gfx::Rect flipped_scissor = scissor_rect_; |
+ flipped_scissor.set_y(ViewportHeight() - scissor_rect_.bottom()); |
+ sk_canvas_->clipRect(gfx::RectToSkRect(flipped_scissor), |
+ 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.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->Raster( |
+ sk_canvas_.get(), quad->content_rect, quad->contents_scale, NULL); |
+ |
+ // Flush any drawing buffers that have been deferred. |
+ sk_canvas_->flush(); |
+ 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( |
@@ -1491,8 +1549,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_, |
@@ -2799,6 +2857,48 @@ void GLRenderer::CleanupSharedObjects() { |
ReleaseRenderPassTextures(); |
} |
+void GLRenderer::ReinitializeGrCanvas() { |
+ if (!CanUseGanesh()) |
+ return; |
+ |
+ GrBackendRenderTargetDesc desc; |
+ desc.fWidth = ViewportWidth(); |
+ desc.fHeight = ViewportHeight(); |
+ desc.fConfig = kRGBA_8888_GrPixelConfig; |
+ desc.fOrigin = kBottomLeft_GrSurfaceOrigin; |
bsalomon
2013/05/13 19:49:15
As of skia r9113 (which should get rolled to chrom
|
+ desc.fSampleCnt = 1; |
+ desc.fStencilBits = 8; |
+ desc.fRenderTargetHandle = 0; |
+ |
+ SkAutoTUnref<GrSurface> surface( |
+ gr_context_->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 gr_context_ && context_->getContextAttributes().stencil; |
+} |
+ |
bool GLRenderer::IsContextLost() { |
return (context_->getGraphicsResetStatusARB() != GL_NO_ERROR); |
} |