Chromium Code Reviews| 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); |
| } |