Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: cc/gl_renderer.cc

Issue 12086036: cc: Clamp texture coordinates in all tile shaders (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@snowscale
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/gl_renderer.h ('k') | cc/shader.h » ('j') | cc/shader.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/gl_renderer.h ('k') | cc/shader.h » ('j') | cc/shader.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698