| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLGpu.h" | 8 #include "GrGLGpu.h" |
| 9 #include "GrGLGLSL.h" | 9 #include "GrGLGLSL.h" |
| 10 #include "GrGLStencilAttachment.h" | 10 #include "GrGLStencilAttachment.h" |
| 11 #include "GrGLTextureRenderTarget.h" | 11 #include "GrGLTextureRenderTarget.h" |
| 12 #include "GrGpuResourcePriv.h" | 12 #include "GrGpuResourcePriv.h" |
| 13 #include "GrMesh.h" |
| 13 #include "GrPipeline.h" | 14 #include "GrPipeline.h" |
| 14 #include "GrPLSGeometryProcessor.h" | 15 #include "GrPLSGeometryProcessor.h" |
| 15 #include "GrRenderTargetPriv.h" | 16 #include "GrRenderTargetPriv.h" |
| 16 #include "GrSurfacePriv.h" | 17 #include "GrSurfacePriv.h" |
| 17 #include "GrTexturePriv.h" | 18 #include "GrTexturePriv.h" |
| 18 #include "GrTypes.h" | 19 #include "GrTypes.h" |
| 19 #include "GrVertices.h" | |
| 20 #include "builders/GrGLShaderStringBuilder.h" | 20 #include "builders/GrGLShaderStringBuilder.h" |
| 21 #include "glsl/GrGLSL.h" | 21 #include "glsl/GrGLSL.h" |
| 22 #include "glsl/GrGLSLCaps.h" | 22 #include "glsl/GrGLSLCaps.h" |
| 23 #include "glsl/GrGLSLPLSPathRendering.h" | 23 #include "glsl/GrGLSLPLSPathRendering.h" |
| 24 #include "SkMipMap.h" | 24 #include "SkMipMap.h" |
| 25 #include "SkPixmap.h" | 25 #include "SkPixmap.h" |
| 26 #include "SkStrokeRec.h" | 26 #include "SkStrokeRec.h" |
| 27 #include "SkTemplates.h" | 27 #include "SkTemplates.h" |
| 28 #include "SkTypes.h" | 28 #include "SkTypes.h" |
| 29 | 29 |
| (...skipping 2034 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 fHWScissorSettings.fEnabled = kYes_TriState; | 2064 fHWScissorSettings.fEnabled = kYes_TriState; |
| 2065 } | 2065 } |
| 2066 return; | 2066 return; |
| 2067 } | 2067 } |
| 2068 } | 2068 } |
| 2069 | 2069 |
| 2070 // See fall through note above | 2070 // See fall through note above |
| 2071 this->disableScissor(); | 2071 this->disableScissor(); |
| 2072 } | 2072 } |
| 2073 | 2073 |
| 2074 bool GrGLGpu::flushGLState(const DrawArgs& args) { | 2074 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
r& primProc) { |
| 2075 GrXferProcessor::BlendInfo blendInfo; | 2075 GrXferProcessor::BlendInfo blendInfo; |
| 2076 const GrPipeline& pipeline = *args.fPipeline; | 2076 pipeline.getXferProcessor().getBlendInfo(&blendInfo); |
| 2077 args.fPipeline->getXferProcessor().getBlendInfo(&blendInfo); | |
| 2078 | 2077 |
| 2079 this->flushColorWrite(blendInfo.fWriteColor); | 2078 this->flushColorWrite(blendInfo.fWriteColor); |
| 2080 this->flushDrawFace(pipeline.getDrawFace()); | 2079 this->flushDrawFace(pipeline.getDrawFace()); |
| 2081 | 2080 |
| 2082 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(args)); | 2081 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline,
primProc)); |
| 2083 if (!program) { | 2082 if (!program) { |
| 2084 GrCapsDebugf(this->caps(), "Failed to create program!\n"); | 2083 GrCapsDebugf(this->caps(), "Failed to create program!\n"); |
| 2085 return false; | 2084 return false; |
| 2086 } | 2085 } |
| 2087 | 2086 |
| 2088 GrGLuint programID = program->programID(); | 2087 GrGLuint programID = program->programID(); |
| 2089 if (fHWProgramID != programID) { | 2088 if (fHWProgramID != programID) { |
| 2090 GL_CALL(UseProgram(programID)); | 2089 GL_CALL(UseProgram(programID)); |
| 2091 fHWProgramID = programID; | 2090 fHWProgramID = programID; |
| 2092 } | 2091 } |
| 2093 | 2092 |
| 2094 if (blendInfo.fWriteColor) { | 2093 if (blendInfo.fWriteColor) { |
| 2095 // Swizzle the blend to match what the shader will output. | 2094 // Swizzle the blend to match what the shader will output. |
| 2096 const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzl
e( | 2095 const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzl
e( |
| 2097 args.fPipeline->getRenderTarget()->config()); | 2096 pipeline.getRenderTarget()->config()); |
| 2098 this->flushBlend(blendInfo, swizzle); | 2097 this->flushBlend(blendInfo, swizzle); |
| 2099 } | 2098 } |
| 2100 | 2099 |
| 2101 SkSTArray<8, const GrTextureAccess*> textureAccesses; | 2100 SkSTArray<8, const GrTextureAccess*> textureAccesses; |
| 2102 program->setData(*args.fPrimitiveProcessor, pipeline, &textureAccesses); | 2101 program->setData(primProc, pipeline, &textureAccesses); |
| 2103 | 2102 |
| 2104 int numTextureAccesses = textureAccesses.count(); | 2103 int numTextureAccesses = textureAccesses.count(); |
| 2105 for (int i = 0; i < numTextureAccesses; i++) { | 2104 for (int i = 0; i < numTextureAccesses; i++) { |
| 2106 this->bindTexture(i, textureAccesses[i]->getParams(), | 2105 this->bindTexture(i, textureAccesses[i]->getParams(), |
| 2107 static_cast<GrGLTexture*>(textureAccesses[i]->getTextu
re())); | 2106 static_cast<GrGLTexture*>(textureAccesses[i]->getTextu
re())); |
| 2108 } | 2107 } |
| 2109 | 2108 |
| 2110 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); | 2109 GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(pipeline.getRenderTa
rget()); |
| 2111 this->flushStencil(pipeline.getStencil()); | 2110 this->flushStencil(pipeline.getStencil()); |
| 2112 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); | 2111 this->flushScissor(pipeline.getScissorState(), glRT->getViewport(), glRT->or
igin()); |
| 2113 this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStenc
il().isDisabled()); | 2112 this->flushHWAAState(glRT, pipeline.isHWAntialiasState(), !pipeline.getStenc
il().isDisabled()); |
| 2114 | 2113 |
| 2115 // This must come after textures are flushed because a texture may need | 2114 // This must come after textures are flushed because a texture may need |
| 2116 // to be msaa-resolved (which will modify bound FBO state). | 2115 // to be msaa-resolved (which will modify bound FBO state). |
| 2117 this->flushRenderTarget(glRT, nullptr); | 2116 this->flushRenderTarget(glRT, nullptr); |
| 2118 | 2117 |
| 2119 return true; | 2118 return true; |
| 2120 } | 2119 } |
| 2121 | 2120 |
| 2122 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, | 2121 void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc, |
| 2123 const GrNonInstancedVertices& vertices, | 2122 const GrNonInstancedMesh& mesh, |
| 2124 size_t* indexOffsetInBytes) { | 2123 size_t* indexOffsetInBytes) { |
| 2125 GrGLVertexBuffer* vbuf; | 2124 GrGLVertexBuffer* vbuf; |
| 2126 vbuf = (GrGLVertexBuffer*) vertices.vertexBuffer(); | 2125 vbuf = (GrGLVertexBuffer*) mesh.vertexBuffer(); |
| 2127 | 2126 |
| 2128 SkASSERT(vbuf); | 2127 SkASSERT(vbuf); |
| 2129 SkASSERT(!vbuf->isMapped()); | 2128 SkASSERT(!vbuf->isMapped()); |
| 2130 | 2129 |
| 2131 GrGLIndexBuffer* ibuf = nullptr; | 2130 GrGLIndexBuffer* ibuf = nullptr; |
| 2132 if (vertices.isIndexed()) { | 2131 if (mesh.isIndexed()) { |
| 2133 SkASSERT(indexOffsetInBytes); | 2132 SkASSERT(indexOffsetInBytes); |
| 2134 | 2133 |
| 2135 *indexOffsetInBytes = 0; | 2134 *indexOffsetInBytes = 0; |
| 2136 ibuf = (GrGLIndexBuffer*)vertices.indexBuffer(); | 2135 ibuf = (GrGLIndexBuffer*)mesh.indexBuffer(); |
| 2137 | 2136 |
| 2138 SkASSERT(ibuf); | 2137 SkASSERT(ibuf); |
| 2139 SkASSERT(!ibuf->isMapped()); | 2138 SkASSERT(!ibuf->isMapped()); |
| 2140 *indexOffsetInBytes += ibuf->baseOffset(); | 2139 *indexOffsetInBytes += ibuf->baseOffset(); |
| 2141 } | 2140 } |
| 2142 GrGLAttribArrayState* attribState = | 2141 GrGLAttribArrayState* attribState = |
| 2143 fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); | 2142 fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf); |
| 2144 | 2143 |
| 2145 int vaCount = primProc.numAttribs(); | 2144 int vaCount = primProc.numAttribs(); |
| 2146 if (vaCount > 0) { | 2145 if (vaCount > 0) { |
| 2147 | 2146 |
| 2148 GrGLsizei stride = static_cast<GrGLsizei>(primProc.getVertexStride()); | 2147 GrGLsizei stride = static_cast<GrGLsizei>(primProc.getVertexStride()); |
| 2149 | 2148 |
| 2150 size_t vertexOffsetInBytes = stride * vertices.startVertex(); | 2149 size_t vertexOffsetInBytes = stride * mesh.startVertex(); |
| 2151 | 2150 |
| 2152 vertexOffsetInBytes += vbuf->baseOffset(); | 2151 vertexOffsetInBytes += vbuf->baseOffset(); |
| 2153 | 2152 |
| 2154 uint32_t usedAttribArraysMask = 0; | 2153 uint32_t usedAttribArraysMask = 0; |
| 2155 size_t offset = 0; | 2154 size_t offset = 0; |
| 2156 | 2155 |
| 2157 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { | 2156 for (int attribIndex = 0; attribIndex < vaCount; attribIndex++) { |
| 2158 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); | 2157 const GrGeometryProcessor::Attribute& attrib = primProc.getAttrib(at
tribIndex); |
| 2159 usedAttribArraysMask |= (1 << attribIndex); | 2158 usedAttribArraysMask |= (1 << attribIndex); |
| 2160 GrVertexAttribType attribType = attrib.fType; | 2159 GrVertexAttribType attribType = attrib.fType; |
| 2161 attribState->set(this, | 2160 attribState->set(this, |
| 2162 attribIndex, | 2161 attribIndex, |
| 2163 vbuf->bufferID(), | 2162 vbuf->bufferID(), |
| 2164 attribType, | 2163 attribType, |
| 2165 stride, | 2164 stride, |
| 2166 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o
ffset)); | 2165 reinterpret_cast<GrGLvoid*>(vertexOffsetInBytes + o
ffset)); |
| 2167 offset += attrib.fOffset; | 2166 offset += attrib.fOffset; |
| 2168 } | 2167 } |
| 2169 attribState->disableUnusedArrays(this, usedAttribArraysMask); | 2168 attribState->disableUnusedArrays(this, usedAttribArraysMask); |
| 2170 } | 2169 } |
| 2171 } | 2170 } |
| 2172 | 2171 |
| 2173 void GrGLGpu::buildProgramDesc(GrProgramDesc* desc, | |
| 2174 const GrPrimitiveProcessor& primProc, | |
| 2175 const GrPipeline& pipeline) const { | |
| 2176 if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, *this->glCaps()
.glslCaps())) { | |
| 2177 SkDEBUGFAIL("Failed to generate GL program descriptor"); | |
| 2178 } | |
| 2179 } | |
| 2180 | |
| 2181 void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) { | 2172 void GrGLGpu::bindBuffer(GrGLuint id, GrGLenum type) { |
| 2182 this->handleDirtyContext(); | 2173 this->handleDirtyContext(); |
| 2183 switch (type) { | 2174 switch (type) { |
| 2184 case GR_GL_ARRAY_BUFFER: | 2175 case GR_GL_ARRAY_BUFFER: |
| 2185 this->bindVertexBuffer(id); | 2176 this->bindVertexBuffer(id); |
| 2186 break; | 2177 break; |
| 2187 case GR_GL_ELEMENT_ARRAY_BUFFER: | 2178 case GR_GL_ELEMENT_ARRAY_BUFFER: |
| 2188 this->bindIndexBufferAndDefaultVertexArray(id); | 2179 this->bindIndexBufferAndDefaultVertexArray(id); |
| 2189 break; | 2180 break; |
| 2190 case GR_GL_TEXTURE_BUFFER: | 2181 case GR_GL_TEXTURE_BUFFER: |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2911 GetWindowThreadProcessId(hwnd, &wndProcID); | 2902 GetWindowThreadProcessId(hwnd, &wndProcID); |
| 2912 if(wndProcID == procID) { | 2903 if(wndProcID == procID) { |
| 2913 SwapBuffers(GetDC(hwnd)); | 2904 SwapBuffers(GetDC(hwnd)); |
| 2914 } | 2905 } |
| 2915 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); | 2906 hwnd = GetNextWindow(hwnd, GW_HWNDNEXT); |
| 2916 } | 2907 } |
| 2917 } | 2908 } |
| 2918 #endif | 2909 #endif |
| 2919 #endif | 2910 #endif |
| 2920 | 2911 |
| 2921 void GrGLGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice
s) { | 2912 void GrGLGpu::onDraw(const GrPipeline& pipeline, |
| 2922 if (!this->flushGLState(args)) { | 2913 const GrPrimitiveProcessor& primProc, |
| 2914 const GrMesh* meshes, |
| 2915 int meshCount) { |
| 2916 if (!this->flushGLState(pipeline, primProc)) { |
| 2923 return; | 2917 return; |
| 2924 } | 2918 } |
| 2925 | 2919 GrPixelLocalStorageState plsState = primProc.getPixelLocalStorageState(); |
| 2926 GrPixelLocalStorageState plsState = args.fPrimitiveProcessor->getPixelLocalS
torageState(); | 2920 if (!fHWPLSEnabled && plsState != |
| 2927 if (!fHWPLSEnabled && plsState != | |
| 2928 GrPixelLocalStorageState::kDisabled_GrPixelLocalStorageState) { | 2921 GrPixelLocalStorageState::kDisabled_GrPixelLocalStorageState) { |
| 2929 GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE)); | 2922 GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE)); |
| 2930 this->setupPixelLocalStorage(args); | 2923 this->setupPixelLocalStorage(pipeline, primProc); |
| 2931 fHWPLSEnabled = true; | 2924 fHWPLSEnabled = true; |
| 2932 } | 2925 } |
| 2933 if (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState)
{ | 2926 if (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState)
{ |
| 2934 GrStencilSettings stencil; | 2927 GrStencilSettings stencil; |
| 2935 stencil.setDisabled(); | 2928 stencil.setDisabled(); |
| 2936 this->flushStencil(stencil); | 2929 this->flushStencil(stencil); |
| 2937 } | 2930 } |
| 2938 | 2931 |
| 2939 size_t indexOffsetInBytes = 0; | 2932 for (int i = 0; i < meshCount; ++i) { |
| 2940 this->setupGeometry(*args.fPrimitiveProcessor, vertices, &indexOffsetInBytes
); | 2933 if (GrXferBarrierType barrierType = pipeline.xferBarrierType(*this->caps
())) { |
| 2934 this->xferBarrier(pipeline.getRenderTarget(), barrierType); |
| 2935 } |
| 2941 | 2936 |
| 2942 SkASSERT((size_t)vertices.primitiveType() < SK_ARRAY_COUNT(gPrimitiveType2GL
Mode)); | 2937 const GrMesh& mesh = meshes[i]; |
| 2943 | 2938 GrMesh::Iterator iter; |
| 2944 if (vertices.isIndexed()) { | 2939 const GrNonInstancedMesh* nonIdxMesh = iter.init(mesh); |
| 2945 GrGLvoid* indices = | 2940 do { |
| 2946 reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint16_t) * | 2941 size_t indexOffsetInBytes = 0; |
| 2947 vertices.startIndex()); | 2942 this->setupGeometry(primProc, *nonIdxMesh, &indexOffsetInBytes); |
| 2948 // info.startVertex() was accounted for by setupGeometry. | 2943 if (nonIdxMesh->isIndexed()) { |
| 2949 GL_CALL(DrawElements(gPrimitiveType2GLMode[vertices.primitiveType()], | 2944 GrGLvoid* indices = |
| 2950 vertices.indexCount(), | 2945 reinterpret_cast<GrGLvoid*>(indexOffsetInBytes + sizeof(uint
16_t) * |
| 2951 GR_GL_UNSIGNED_SHORT, | 2946 nonIdxMesh->startIndex()); |
| 2952 indices)); | 2947 // info.startVertex() was accounted for by setupGeometry. |
| 2953 } else { | 2948 GL_CALL(DrawElements(gPrimitiveType2GLMode[nonIdxMesh->primitive
Type()], |
| 2954 // Pass 0 for parameter first. We have to adjust glVertexAttribPointer()
to account for | 2949 nonIdxMesh->indexCount(), |
| 2955 // startVertex in the DrawElements case. So we always rely on setupGeome
try to have | 2950 GR_GL_UNSIGNED_SHORT, |
| 2956 // accounted for startVertex. | 2951 indices)); |
| 2957 GL_CALL(DrawArrays(gPrimitiveType2GLMode[vertices.primitiveType()], 0, | 2952 } else { |
| 2958 vertices.vertexCount())); | 2953 // Pass 0 for parameter first. We have to adjust glVertexAttribP
ointer() to account |
| 2954 // for startVertex in the DrawElements case. So we always rely o
n setupGeometry to |
| 2955 // have accounted for startVertex. |
| 2956 GL_CALL(DrawArrays(gPrimitiveType2GLMode[nonIdxMesh->primitiveTy
pe()], 0, |
| 2957 nonIdxMesh->vertexCount())); |
| 2958 } |
| 2959 fStats.incNumDraws(); |
| 2960 } while ((nonIdxMesh = iter.next())); |
| 2959 } | 2961 } |
| 2960 | 2962 |
| 2961 if (fHWPLSEnabled && plsState == GrPixelLocalStorageState::kFinish_GrPixelLo
calStorageState) { | 2963 if (fHWPLSEnabled && plsState == GrPixelLocalStorageState::kFinish_GrPixelLo
calStorageState) { |
| 2962 // PLS draws always involve multiple draws, finishing up with a non-PLS | 2964 // PLS draws always involve multiple draws, finishing up with a non-PLS |
| 2963 // draw that writes to the color buffer. That draw ends up here; we wait | 2965 // draw that writes to the color buffer. That draw ends up here; we wait |
| 2964 // until after it is complete to actually disable PLS. | 2966 // until after it is complete to actually disable PLS. |
| 2965 GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE)); | 2967 GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE)); |
| 2966 fHWPLSEnabled = false; | 2968 fHWPLSEnabled = false; |
| 2967 this->disableScissor(); | 2969 this->disableScissor(); |
| 2968 } | 2970 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3002 if (!fHWStencilSettings.isDisabled()) { | 3004 if (!fHWStencilSettings.isDisabled()) { |
| 3003 GL_CALL(Disable(GR_GL_STENCIL_TEST)); | 3005 GL_CALL(Disable(GR_GL_STENCIL_TEST)); |
| 3004 } | 3006 } |
| 3005 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); | 3007 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); |
| 3006 GL_CALL(UseProgram(fHWProgramID)); | 3008 GL_CALL(UseProgram(fHWProgramID)); |
| 3007 if (!fHWStencilSettings.isDisabled()) { | 3009 if (!fHWStencilSettings.isDisabled()) { |
| 3008 GL_CALL(Enable(GR_GL_STENCIL_TEST)); | 3010 GL_CALL(Enable(GR_GL_STENCIL_TEST)); |
| 3009 } | 3011 } |
| 3010 } | 3012 } |
| 3011 | 3013 |
| 3012 void GrGLGpu::setupPixelLocalStorage(const DrawArgs& args) { | 3014 void GrGLGpu::setupPixelLocalStorage(const GrPipeline& pipeline, |
| 3015 const GrPrimitiveProcessor& primProc) { |
| 3013 fPLSHasBeenUsed = true; | 3016 fPLSHasBeenUsed = true; |
| 3014 const SkRect& bounds = | 3017 const SkRect& bounds = |
| 3015 static_cast<const GrPLSGeometryProcessor*>(args.fPrimitiveProcessor)
->getBounds(); | 3018 static_cast<const GrPLSGeometryProcessor&>(primProc).getBounds(); |
| 3016 // setup pixel local storage -- this means capturing and storing the current
framebuffer color | 3019 // setup pixel local storage -- this means capturing and storing the current
framebuffer color |
| 3017 // and initializing the winding counts to zero | 3020 // and initializing the winding counts to zero |
| 3018 GrRenderTarget* rt = args.fPipeline->getRenderTarget(); | 3021 GrRenderTarget* rt = pipeline.getRenderTarget(); |
| 3019 SkScalar width = SkIntToScalar(rt->width()); | 3022 SkScalar width = SkIntToScalar(rt->width()); |
| 3020 SkScalar height = SkIntToScalar(rt->height()); | 3023 SkScalar height = SkIntToScalar(rt->height()); |
| 3021 // dst rect edges in NDC (-1 to 1) | 3024 // dst rect edges in NDC (-1 to 1) |
| 3022 // having some issues with rounding, just expand the bounds by 1 and trust t
he scissor to keep | 3025 // having some issues with rounding, just expand the bounds by 1 and trust t
he scissor to keep |
| 3023 // it contained properly | 3026 // it contained properly |
| 3024 GrGLfloat dx0 = 2.0f * (bounds.left() - 1) / width - 1.0f; | 3027 GrGLfloat dx0 = 2.0f * (bounds.left() - 1) / width - 1.0f; |
| 3025 GrGLfloat dx1 = 2.0f * (bounds.right() + 1) / width - 1.0f; | 3028 GrGLfloat dx1 = 2.0f * (bounds.right() + 1) / width - 1.0f; |
| 3026 GrGLfloat dy0 = -2.0f * (bounds.top() - 1) / height + 1.0f; | 3029 GrGLfloat dy0 = -2.0f * (bounds.top() - 1) / height + 1.0f; |
| 3027 GrGLfloat dy1 = -2.0f * (bounds.bottom() + 1) / height + 1.0f; | 3030 GrGLfloat dy1 = -2.0f * (bounds.bottom() + 1) / height + 1.0f; |
| 3028 SkRect deviceBounds = SkRect::MakeXYWH(dx0, dy0, dx1 - dx0, dy1 - dy0); | 3031 SkRect deviceBounds = SkRect::MakeXYWH(dx0, dy0, dx1 - dx0, dy1 - dy0); |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4387 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || | 4390 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
| 4388 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4391 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
| 4389 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4392 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
| 4390 copyParams->fWidth = texture->width(); | 4393 copyParams->fWidth = texture->width(); |
| 4391 copyParams->fHeight = texture->height(); | 4394 copyParams->fHeight = texture->height(); |
| 4392 return true; | 4395 return true; |
| 4393 } | 4396 } |
| 4394 } | 4397 } |
| 4395 return false; | 4398 return false; |
| 4396 } | 4399 } |
| OLD | NEW |