| 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);
|
| }
|
|
|