| Index: cc/gl_renderer.cc
|
| diff --git a/cc/gl_renderer.cc b/cc/gl_renderer.cc
|
| index e9f8254a16b5629a6033aeb278a040d58821218d..424a571ed3dee354603f001320271586c0a30687 100644
|
| --- a/cc/gl_renderer.cc
|
| +++ b/cc/gl_renderer.cc
|
| @@ -685,18 +685,131 @@ void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
|
| m_context->flush();
|
| }
|
|
|
| +struct SolidColorProgramUniforms {
|
| + unsigned program;
|
| + unsigned matrixLocation;
|
| + unsigned colorLocation;
|
| + unsigned pointLocation;
|
| + unsigned texScaleLocation;
|
| + unsigned edgeLocation;
|
| +};
|
| +
|
| +template<class T>
|
| +static void solidColorUniformLocation(T program, SolidColorProgramUniforms& uniforms)
|
| +{
|
| + uniforms.program = program->program();
|
| + uniforms.matrixLocation = program->vertexShader().matrixLocation();
|
| + uniforms.colorLocation = program->fragmentShader().colorLocation();
|
| + uniforms.pointLocation = program->vertexShader().pointLocation();
|
| + uniforms.texScaleLocation = program->vertexShader().texScaleLocation();
|
| + uniforms.edgeLocation = program->fragmentShader().edgeLocation();
|
| +}
|
| +
|
| void GLRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorDrawQuad* quad)
|
| {
|
| - const SolidColorProgram* program = solidColorProgram();
|
| - setUseProgram(program->program());
|
| + gfx::Rect tileRect = quad->visible_rect;
|
| +
|
| + gfx::QuadF localQuad;
|
| + gfx::Transform deviceTransform = MathUtil::to2dTransform(frame.windowMatrix * frame.projectionMatrix * quad->quadTransform());
|
| + if (!deviceTransform.IsInvertible())
|
| + return;
|
| +
|
| + bool clipped = false;
|
| + gfx::QuadF deviceLayerQuad = MathUtil::mapQuad(deviceTransform, gfx::QuadF(quad->visibleContentRect()), clipped);
|
| + DCHECK(!clipped);
|
| +
|
| + SolidColorProgramUniforms uniforms;
|
| + // For now, we simply skip anti-aliasing with the quad is clipped. This only happens
|
| + // on perspective transformed layers that go partially behind the camera.
|
| + if (quad->IsAntialiased() && !clipped)
|
| + solidColorUniformLocation(solidColorProgramAA(), uniforms);
|
| + else
|
| + solidColorUniformLocation(solidColorProgram(), uniforms);
|
| +
|
| + setUseProgram(uniforms.program);
|
|
|
| SkColor color = quad->color;
|
| float opacity = quad->opacity();
|
| float alpha = (SkColorGetA(color) / 255.0) * opacity;
|
|
|
| - GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation(), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, (SkColorGetB(color) / 255.0) * alpha, alpha));
|
| + GLC(context(), context()->uniform4f(uniforms.colorLocation, (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, (SkColorGetB(color) / 255.0) * alpha, alpha));
|
|
|
| - drawQuadGeometry(frame, quad->quadTransform(), quad->rect, program->vertexShader().matrixLocation());
|
| + GLC(context(), context()->uniform2f(uniforms.texScaleLocation, 1.0f, 1.0f));
|
| +
|
| + bool useAA = !clipped && quad->IsAntialiased();
|
| + if (useAA) {
|
| + LayerQuad deviceLayerBounds = LayerQuad(gfx::QuadF(deviceLayerQuad.BoundingBox()));
|
| + deviceLayerBounds.inflateAntiAliasingDistance();
|
| +
|
| + LayerQuad deviceLayerEdges = LayerQuad(deviceLayerQuad);
|
| + deviceLayerEdges.inflateAntiAliasingDistance();
|
| +
|
| + float edge[24];
|
| + deviceLayerEdges.toFloatArray(edge);
|
| + deviceLayerBounds.toFloatArray(&edge[12]);
|
| + GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge));
|
| +
|
| + gfx::PointF bottomRight = tileRect.bottom_right();
|
| + gfx::PointF bottomLeft = tileRect.bottom_left();
|
| + gfx::PointF topLeft = tileRect.origin();
|
| + gfx::PointF topRight = tileRect.top_right();
|
| +
|
| + // Map points to device space.
|
| + bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped);
|
| + DCHECK(!clipped);
|
| + bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped);
|
| + DCHECK(!clipped);
|
| + topLeft = MathUtil::mapPoint(deviceTransform, topLeft, clipped);
|
| + DCHECK(!clipped);
|
| + topRight = MathUtil::mapPoint(deviceTransform, topRight, clipped);
|
| + DCHECK(!clipped);
|
| +
|
| + LayerQuad::Edge bottomEdge(bottomRight, bottomLeft);
|
| + LayerQuad::Edge leftEdge(bottomLeft, topLeft);
|
| + LayerQuad::Edge topEdge(topLeft, topRight);
|
| + LayerQuad::Edge rightEdge(topRight, bottomRight);
|
| +
|
| + // Only apply anti-aliasing to edges not clipped by culling or scissoring.
|
| + if (quad->top_edge_aa && tileRect.y() == quad->rect.y())
|
| + topEdge = deviceLayerEdges.top();
|
| + if (quad->left_edge_aa && tileRect.x() == quad->rect.x())
|
| + leftEdge = deviceLayerEdges.left();
|
| + if (quad->right_edge_aa && tileRect.right() == quad->rect.right())
|
| + rightEdge = deviceLayerEdges.right();
|
| + if (quad->bottom_edge_aa && tileRect.bottom() == quad->rect.bottom())
|
| + bottomEdge = deviceLayerEdges.bottom();
|
| +
|
| + float sign = gfx::QuadF(tileRect).IsCounterClockwise() ? -1 : 1;
|
| + bottomEdge.scale(sign);
|
| + leftEdge.scale(sign);
|
| + topEdge.scale(sign);
|
| + rightEdge.scale(sign);
|
| +
|
| + // Create device space quad.
|
| + LayerQuad deviceQuad(leftEdge, topEdge, rightEdge, bottomEdge);
|
| +
|
| + // Map device space quad to local space. deviceTransform has no 3d component since it was generated with to2dTransform() so we don't need to project.
|
| + gfx::Transform deviceTransformInverse = MathUtil::inverse(deviceTransform);
|
| + localQuad = MathUtil::mapQuad(deviceTransformInverse, deviceQuad.ToQuadF(), clipped);
|
| +
|
| + // We should not DCHECK(!clipped) here, because anti-aliasing inflation may cause deviceQuad to become
|
| + // clipped. To our knowledge this scenario does not need to be handled differently than the unclipped case.
|
| + } else {
|
| + localQuad = gfx::RectF(tileRect);
|
| + }
|
| +
|
| + // Normalize to tileRect.
|
| + localQuad.Scale(1.0f / tileRect.width(), 1.0f / tileRect.height());
|
| +
|
| + setShaderQuadF(localQuad, uniforms.pointLocation);
|
| +
|
| + // The tile quad shader behaves differently compared to all other shaders.
|
| + // The transform and vertex data are used to figure out the extents that the
|
| + // un-antialiased quad should have and which vertex this is and the float
|
| + // quad passed in via uniform is the actual geometry that gets used to draw
|
| + // it. This is why this centered rect is used and not the original quadRect.
|
| + gfx::RectF centeredRect(gfx::PointF(-0.5 * tileRect.width(), -0.5 * tileRect.height()), tileRect.size());
|
| + drawQuadGeometry(frame, quad->quadTransform(), centeredRect, uniforms.matrixLocation);
|
| }
|
|
|
| struct TileProgramUniforms {
|
| @@ -1585,6 +1698,17 @@ const GLRenderer::SolidColorProgram* GLRenderer::solidColorProgram()
|
| return m_solidColorProgram.get();
|
| }
|
|
|
| +const GLRenderer::SolidColorProgramAA* GLRenderer::solidColorProgramAA()
|
| +{
|
| + if (!m_solidColorProgramAA)
|
| + m_solidColorProgramAA = make_scoped_ptr(new SolidColorProgramAA(m_context));
|
| + if (!m_solidColorProgramAA->initialized()) {
|
| + TRACE_EVENT0("cc", "GLRenderer::solidColorProgramAA::initialize");
|
| + m_solidColorProgramAA->initialize(m_context, m_isUsingBindUniform);
|
| + }
|
| + return m_solidColorProgramAA.get();
|
| +}
|
| +
|
| const GLRenderer::RenderPassProgram* GLRenderer::renderPassProgram()
|
| {
|
| DCHECK(m_renderPassProgram);
|
| @@ -1791,6 +1915,8 @@ void GLRenderer::cleanupSharedObjects()
|
|
|
| if (m_solidColorProgram)
|
| m_solidColorProgram->cleanup(m_context);
|
| + if (m_solidColorProgramAA)
|
| + m_solidColorProgramAA->cleanup(m_context);
|
|
|
| if (m_offscreenFramebufferId)
|
| GLC(m_context, m_context->deleteFramebuffer(m_offscreenFramebufferId));
|
|
|