Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/gl_renderer.h" | 5 #include "cc/gl_renderer.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 691 | 691 |
| 692 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha)); | 692 GLC(context(), context()->uniform4f(program->fragmentShader().colorLocation( ), (SkColorGetR(color) / 255.0) * alpha, (SkColorGetG(color) / 255.0) * alpha, ( SkColorGetB(color) / 255.0) * alpha, alpha)); |
| 693 | 693 |
| 694 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, program->vertexSh ader().matrixLocation()); | 694 drawQuadGeometry(frame, quad->quadTransform(), quad->rect, program->vertexSh ader().matrixLocation()); |
| 695 } | 695 } |
| 696 | 696 |
| 697 struct TileProgramUniforms { | 697 struct TileProgramUniforms { |
| 698 unsigned program; | 698 unsigned program; |
| 699 unsigned samplerLocation; | 699 unsigned samplerLocation; |
| 700 unsigned vertexTexTransformLocation; | 700 unsigned vertexTexTransformLocation; |
| 701 unsigned fragmentTexTransformLocation; | 701 unsigned fragmentTexClampLocation; |
| 702 unsigned edgeLocation; | 702 unsigned edgeLocation; |
| 703 unsigned matrixLocation; | 703 unsigned matrixLocation; |
| 704 unsigned alphaLocation; | 704 unsigned alphaLocation; |
| 705 unsigned pointLocation; | 705 unsigned pointLocation; |
| 706 }; | 706 }; |
| 707 | 707 |
| 708 template<class T> | 708 template<class T> |
| 709 static void tileUniformLocation(T program, TileProgramUniforms& uniforms) | 709 static void tileUniformLocation(T program, TileProgramUniforms& uniforms) |
| 710 { | 710 { |
| 711 uniforms.program = program->program(); | 711 uniforms.program = program->program(); |
| 712 uniforms.vertexTexTransformLocation = program->vertexShader().vertexTexTrans formLocation(); | 712 uniforms.vertexTexTransformLocation = program->vertexShader().vertexTexTrans formLocation(); |
| 713 uniforms.matrixLocation = program->vertexShader().matrixLocation(); | 713 uniforms.matrixLocation = program->vertexShader().matrixLocation(); |
| 714 uniforms.pointLocation = program->vertexShader().pointLocation(); | 714 uniforms.pointLocation = program->vertexShader().pointLocation(); |
| 715 | 715 |
| 716 uniforms.samplerLocation = program->fragmentShader().samplerLocation(); | 716 uniforms.samplerLocation = program->fragmentShader().samplerLocation(); |
| 717 uniforms.alphaLocation = program->fragmentShader().alphaLocation(); | 717 uniforms.alphaLocation = program->fragmentShader().alphaLocation(); |
| 718 uniforms.fragmentTexTransformLocation = program->fragmentShader().fragmentTe xTransformLocation(); | 718 uniforms.fragmentTexClampLocation = program->fragmentShader().fragmentTexCla mpLocation(); |
| 719 uniforms.edgeLocation = program->fragmentShader().edgeLocation(); | 719 uniforms.edgeLocation = program->fragmentShader().edgeLocation(); |
| 720 } | 720 } |
| 721 | 721 |
| 722 void GLRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* qua d) | 722 void GLRenderer::drawTileQuad(const DrawingFrame& frame, const TileDrawQuad* qua d) |
| 723 { | 723 { |
| 724 gfx::Rect tileRect = quad->visible_rect; | 724 gfx::Rect tileRect = quad->visible_rect; |
| 725 gfx::RectF texCoordRect = quad->tex_coord_rect; | |
| 726 const gfx::Size& textureSize = quad->texture_size; | |
| 725 | 727 |
| 726 gfx::RectF texCoordRect = quad->tex_coord_rect; | |
| 727 float texToGeomScaleX = quad->rect.width() / texCoordRect.width(); | 728 float texToGeomScaleX = quad->rect.width() / texCoordRect.width(); |
| 728 float texToGeomScaleY = quad->rect.height() / texCoordRect.height(); | 729 float texToGeomScaleY = quad->rect.height() / texCoordRect.height(); |
| 729 | 730 |
| 730 // texCoordRect corresponds to quadRect, but quadVisibleRect may be | 731 // texCoordRect corresponds to quadRect, but quadVisibleRect may be |
| 731 // smaller than quadRect due to occlusion or clipping. Adjust | 732 // smaller than quadRect due to occlusion or clipping. Adjust |
| 732 // texCoordRect to match. | 733 // texCoordRect to match. |
| 733 gfx::Vector2d topLeftDiff = tileRect.origin() - quad->rect.origin(); | 734 gfx::Vector2d topLeftDiff = tileRect.origin() - quad->rect.origin(); |
| 734 gfx::Vector2d bottomRightDiff = | 735 gfx::Vector2d bottomRightDiff = |
| 735 tileRect.bottom_right() - quad->rect.bottom_right(); | 736 tileRect.bottom_right() - quad->rect.bottom_right(); |
| 736 texCoordRect.Inset(topLeftDiff.x() / texToGeomScaleX, | 737 texCoordRect.Inset(topLeftDiff.x() / texToGeomScaleX, |
| 737 topLeftDiff.y() / texToGeomScaleY, | 738 topLeftDiff.y() / texToGeomScaleY, |
| 738 -bottomRightDiff.x() / texToGeomScaleX, | 739 -bottomRightDiff.x() / texToGeomScaleX, |
| 739 -bottomRightDiff.y() / texToGeomScaleY); | 740 -bottomRightDiff.y() / texToGeomScaleY); |
| 740 | 741 |
| 741 gfx::RectF clampGeomRect(tileRect); | 742 // Map geometry to texture coordinates in the vertex shader. |
|
brianderson
2013/01/29 03:03:48
I combined the vertex and fragment shader "transfo
| |
| 742 gfx::RectF clampTexRect(texCoordRect); | 743 float vertexTexScaleX = texCoordRect.width() / textureSize.width(); |
| 743 // Clamp texture coordinates to avoid sampling outside the layer | 744 float vertexTexScaleY = texCoordRect.height() / textureSize.height(); |
| 744 // by deflating the tile region half a texel or half a texel | 745 float vertexTexTranslateX = (texCoordRect.x() - (tileRect.x() / texToGeomSca leX)) / textureSize.width(); |
| 745 // minus epsilon for one pixel layers. The resulting clamp region | 746 float vertexTexTranslateY = (texCoordRect.y() - (tileRect.y() / texToGeomSca leY)) / textureSize.height(); |
| 746 // is mapped to the unit square by the vertex shader and mapped | |
| 747 // back to normalized texture coordinates by the fragment shader | |
| 748 // after being clamped to 0-1 range. | |
| 749 const float epsilon = 1 / 1024.0f; | |
| 750 float texClampX = std::min(0.5f, 0.5f * clampTexRect.width() - epsilon); | |
| 751 float texClampY = std::min(0.5f, 0.5f * clampTexRect.height() - epsilon); | |
| 752 float geomClampX = std::min(texClampX * texToGeomScaleX, | |
| 753 0.5f * clampGeomRect.width() - epsilon); | |
| 754 float geomClampY = std::min(texClampY * texToGeomScaleY, | |
| 755 0.5f * clampGeomRect.height() - epsilon); | |
| 756 clampGeomRect.Inset(geomClampX, geomClampY, geomClampX, geomClampY); | |
| 757 clampTexRect.Inset(texClampX, texClampY, texClampX, texClampY); | |
| 758 | 747 |
| 759 // Map clamping rectangle to unit square. | 748 // Manually clamp in the fragment shader. |
|
brianderson
2013/01/29 03:03:48
This logic handles the clamping in the fragment sh
| |
| 760 float vertexTexTranslateX = -clampGeomRect.x() / clampGeomRect.width(); | 749 float fragmentTexClampXMin = (texCoordRect.x() + 0.5f) / textureSize.wi dth(); |
| 761 float vertexTexTranslateY = -clampGeomRect.y() / clampGeomRect.height(); | 750 float fragmentTexClampXMax = (texCoordRect.right() - 0.5f) / textureSize.wi dth(); |
| 762 float vertexTexScaleX = tileRect.width() / clampGeomRect.width(); | 751 float fragmentTexClampYMin = (texCoordRect.y() + 0.5f) / textureSize.he ight(); |
| 763 float vertexTexScaleY = tileRect.height() / clampGeomRect.height(); | 752 float fragmentTexClampYMax = (texCoordRect.bottom() - 0.5f) / textureSize.he ight(); |
| 764 | |
| 765 // Map to normalized texture coordinates. | |
| 766 const gfx::Size& textureSize = quad->texture_size; | |
| 767 float fragmentTexTranslateX = clampTexRect.x() / textureSize.width(); | |
| 768 float fragmentTexTranslateY = clampTexRect.y() / textureSize.height(); | |
| 769 float fragmentTexScaleX = clampTexRect.width() / textureSize.width(); | |
| 770 float fragmentTexScaleY = clampTexRect.height() / textureSize.height(); | |
| 771 | |
| 772 | 753 |
| 773 gfx::QuadF localQuad; | 754 gfx::QuadF localQuad; |
| 774 gfx::Transform deviceTransform = frame.windowMatrix * frame.projectionMatrix * quad->quadTransform(); | 755 gfx::Transform deviceTransform = frame.windowMatrix * frame.projectionMatrix * quad->quadTransform(); |
| 775 deviceTransform.FlattenTo2d(); | 756 deviceTransform.FlattenTo2d(); |
| 776 if (!deviceTransform.IsInvertible()) | 757 if (!deviceTransform.IsInvertible()) |
| 777 return; | 758 return; |
| 778 | 759 |
| 779 bool clipped = false; | 760 bool clipped = false; |
| 780 gfx::QuadF deviceLayerQuad = MathUtil::mapQuad(deviceTransform, gfx::QuadF(q uad->visibleContentRect()), clipped); | 761 gfx::QuadF deviceLayerQuad = MathUtil::mapQuad(deviceTransform, gfx::QuadF(q uad->visibleContentRect()), clipped); |
| 781 DCHECK(!clipped); | 762 DCHECK(!clipped); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 815 | 796 |
| 816 LayerQuad deviceLayerEdges = LayerQuad(deviceLayerQuad); | 797 LayerQuad deviceLayerEdges = LayerQuad(deviceLayerQuad); |
| 817 deviceLayerEdges.inflateAntiAliasingDistance(); | 798 deviceLayerEdges.inflateAntiAliasingDistance(); |
| 818 | 799 |
| 819 float edge[24]; | 800 float edge[24]; |
| 820 deviceLayerEdges.toFloatArray(edge); | 801 deviceLayerEdges.toFloatArray(edge); |
| 821 deviceLayerBounds.toFloatArray(&edge[12]); | 802 deviceLayerBounds.toFloatArray(&edge[12]); |
| 822 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge)); | 803 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge)); |
| 823 | 804 |
| 824 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); | 805 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); |
| 825 GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocatio n, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexS caleY)); | 806 GLC(context(), context()->uniform4f(uniforms.fragmentTexClampLocation, f ragmentTexClampXMin, fragmentTexClampYMin, fragmentTexClampXMax, fragmentTexClam pYMax)); |
| 826 | 807 |
| 827 gfx::PointF bottomRight = tileRect.bottom_right(); | 808 gfx::PointF bottomRight = tileRect.bottom_right(); |
| 828 gfx::PointF bottomLeft = tileRect.bottom_left(); | 809 gfx::PointF bottomLeft = tileRect.bottom_left(); |
| 829 gfx::PointF topLeft = tileRect.origin(); | 810 gfx::PointF topLeft = tileRect.origin(); |
| 830 gfx::PointF topRight = tileRect.top_right(); | 811 gfx::PointF topRight = tileRect.top_right(); |
| 831 | 812 |
| 832 // Map points to device space. | 813 // Map points to device space. |
| 833 bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped); | 814 bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped); |
| 834 DCHECK(!clipped); | 815 DCHECK(!clipped); |
| 835 bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped); | 816 bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 866 // Map device space quad to local space. deviceTransform has no 3d compo nent since it was flattened, so we don't need to project. | 847 // Map device space quad to local space. deviceTransform has no 3d compo nent since it was flattened, so we don't need to project. |
| 867 // We should have already checked that the transform was uninvertible ab ove. | 848 // We should have already checked that the transform was uninvertible ab ove. |
| 868 gfx::Transform inverseDeviceTransform(gfx::Transform::kSkipInitializatio n); | 849 gfx::Transform inverseDeviceTransform(gfx::Transform::kSkipInitializatio n); |
| 869 bool didInvert = deviceTransform.GetInverse(&inverseDeviceTransform); | 850 bool didInvert = deviceTransform.GetInverse(&inverseDeviceTransform); |
| 870 DCHECK(didInvert); | 851 DCHECK(didInvert); |
| 871 localQuad = MathUtil::mapQuad(inverseDeviceTransform, deviceQuad.ToQuadF (), clipped); | 852 localQuad = MathUtil::mapQuad(inverseDeviceTransform, deviceQuad.ToQuadF (), clipped); |
| 872 | 853 |
| 873 // We should not DCHECK(!clipped) here, because anti-aliasing inflation may cause deviceQuad to become | 854 // We should not DCHECK(!clipped) here, because anti-aliasing inflation may cause deviceQuad to become |
| 874 // clipped. To our knowledge this scenario does not need to be handled d ifferently than the unclipped case. | 855 // clipped. To our knowledge this scenario does not need to be handled d ifferently than the unclipped case. |
| 875 } else { | 856 } else { |
| 876 // Move fragment shader transform to vertex shader. We can do this while | |
| 877 // still producing correct results as fragmentTexTransformLocation | |
| 878 // should always be non-negative when tiles are transformed in a way | |
| 879 // that could result in sampling outside the layer. | |
| 880 vertexTexScaleX *= fragmentTexScaleX; | |
| 881 vertexTexScaleY *= fragmentTexScaleY; | |
| 882 vertexTexTranslateX *= fragmentTexScaleX; | |
| 883 vertexTexTranslateY *= fragmentTexScaleY; | |
| 884 vertexTexTranslateX += fragmentTexTranslateX; | |
| 885 vertexTexTranslateY += fragmentTexTranslateY; | |
| 886 | |
| 887 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); | 857 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation, vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); |
| 888 | 858 GLC(context(), context()->uniform4f(uniforms.fragmentTexClampLocation, f ragmentTexClampXMin, fragmentTexClampYMin, fragmentTexClampXMax, fragmentTexClam pYMax)); |
| 889 localQuad = gfx::RectF(tileRect); | 859 localQuad = gfx::RectF(tileRect); |
| 890 } | 860 } |
| 891 | 861 |
| 892 // Normalize to tileRect. | 862 // Normalize to tileRect. |
| 893 localQuad.Scale(1.0f / tileRect.width(), 1.0f / tileRect.height()); | 863 localQuad.Scale(1.0f / tileRect.width(), 1.0f / tileRect.height()); |
| 894 | 864 |
| 895 setShaderOpacity(quad->opacity(), uniforms.alphaLocation); | 865 setShaderOpacity(quad->opacity(), uniforms.alphaLocation); |
| 896 setShaderQuadF(localQuad, uniforms.pointLocation); | 866 setShaderQuadF(localQuad, uniforms.pointLocation); |
| 897 | 867 |
| 898 // The tile quad shader behaves differently compared to all other shaders. | 868 // The tile quad shader behaves differently compared to all other shaders. |
| (...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1799 | 1769 |
| 1800 releaseRenderPassTextures(); | 1770 releaseRenderPassTextures(); |
| 1801 } | 1771 } |
| 1802 | 1772 |
| 1803 bool GLRenderer::isContextLost() | 1773 bool GLRenderer::isContextLost() |
| 1804 { | 1774 { |
| 1805 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1775 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
| 1806 } | 1776 } |
| 1807 | 1777 |
| 1808 } // namespace cc | 1778 } // namespace cc |
| OLD | NEW |