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 |