Chromium Code Reviews| 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 "GrGLBuffer.h" | 9 #include "GrGLBuffer.h" |
| 10 #include "GrGLGLSL.h" | 10 #include "GrGLGLSL.h" |
| (...skipping 1963 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1974 GL_CALL(MinSampleShading(minSampleShading)); | 1974 GL_CALL(MinSampleShading(minSampleShading)); |
| 1975 } | 1975 } |
| 1976 else { | 1976 else { |
| 1977 GL_CALL(Disable(GR_GL_SAMPLE_SHADING)); | 1977 GL_CALL(Disable(GR_GL_SAMPLE_SHADING)); |
| 1978 } | 1978 } |
| 1979 fHWMinSampleShading = minSampleShading; | 1979 fHWMinSampleShading = minSampleShading; |
| 1980 } | 1980 } |
| 1981 } | 1981 } |
| 1982 | 1982 |
| 1983 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso r& primProc) { | 1983 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso r& primProc) { |
| 1984 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc)); | |
| 1985 if (!program) { | |
| 1986 GrCapsDebugf(this->caps(), "Failed to create program!\n"); | |
| 1987 return false; | |
| 1988 } | |
| 1989 | |
| 1990 program->generateMipmaps(primProc, pipeline); | |
| 1991 | |
| 1984 GrXferProcessor::BlendInfo blendInfo; | 1992 GrXferProcessor::BlendInfo blendInfo; |
| 1985 pipeline.getXferProcessor().getBlendInfo(&blendInfo); | 1993 pipeline.getXferProcessor().getBlendInfo(&blendInfo); |
| 1986 | 1994 |
| 1987 this->flushColorWrite(blendInfo.fWriteColor); | 1995 this->flushColorWrite(blendInfo.fWriteColor); |
| 1988 this->flushDrawFace(pipeline.getDrawFace()); | 1996 this->flushDrawFace(pipeline.getDrawFace()); |
| 1989 this->flushMinSampleShading(primProc.getSampleShading()); | 1997 this->flushMinSampleShading(primProc.getSampleShading()); |
| 1990 | 1998 |
| 1991 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline, primProc)); | |
| 1992 if (!program) { | |
| 1993 GrCapsDebugf(this->caps(), "Failed to create program!\n"); | |
| 1994 return false; | |
| 1995 } | |
| 1996 | |
| 1997 GrGLuint programID = program->programID(); | 1999 GrGLuint programID = program->programID(); |
| 1998 if (fHWProgramID != programID) { | 2000 if (fHWProgramID != programID) { |
| 1999 GL_CALL(UseProgram(programID)); | 2001 GL_CALL(UseProgram(programID)); |
| 2000 fHWProgramID = programID; | 2002 fHWProgramID = programID; |
| 2001 } | 2003 } |
| 2002 | 2004 |
| 2003 if (blendInfo.fWriteColor) { | 2005 if (blendInfo.fWriteColor) { |
| 2004 // Swizzle the blend to match what the shader will output. | 2006 // Swizzle the blend to match what the shader will output. |
| 2005 const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzl e( | 2007 const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzl e( |
| 2006 pipeline.getRenderTarget()->config()); | 2008 pipeline.getRenderTarget()->config()); |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2638 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 2640 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 2639 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x \n", status); | 2641 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x \n", status); |
| 2640 } | 2642 } |
| 2641 } | 2643 } |
| 2642 #endif | 2644 #endif |
| 2643 fHWBoundRenderTargetUniqueID = rtID; | 2645 fHWBoundRenderTargetUniqueID = rtID; |
| 2644 this->flushViewport(target->getViewport()); | 2646 this->flushViewport(target->getViewport()); |
| 2645 } | 2647 } |
| 2646 | 2648 |
| 2647 if (this->glCaps().srgbWriteControl()) { | 2649 if (this->glCaps().srgbWriteControl()) { |
| 2648 bool enableSRGBWrite = GrPixelConfigIsSRGB(target->config()) && !disable SRGB; | 2650 setFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !disableSRGB ); |
|
bsalomon
2016/05/31 16:35:02
this->
Brian Osman
2016/05/31 17:33:05
Done.
| |
| 2649 if (enableSRGBWrite && kYes_TriState != fHWSRGBFramebuffer) { | |
| 2650 GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB)); | |
| 2651 fHWSRGBFramebuffer = kYes_TriState; | |
| 2652 } else if (!enableSRGBWrite && kNo_TriState != fHWSRGBFramebuffer) { | |
| 2653 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); | |
| 2654 fHWSRGBFramebuffer = kNo_TriState; | |
| 2655 } | |
| 2656 } | 2651 } |
| 2657 | 2652 |
| 2658 this->didWriteToSurface(target, bounds); | 2653 this->didWriteToSurface(target, bounds); |
| 2659 } | 2654 } |
| 2660 | 2655 |
| 2656 void GrGLGpu::setFramebufferSRGB(bool enable) { | |
| 2657 if (enable && kYes_TriState != fHWSRGBFramebuffer) { | |
| 2658 GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB)); | |
| 2659 fHWSRGBFramebuffer = kYes_TriState; | |
| 2660 } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) { | |
| 2661 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); | |
| 2662 fHWSRGBFramebuffer = kNo_TriState; | |
| 2663 } | |
| 2664 } | |
| 2665 | |
| 2661 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { | 2666 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { |
| 2662 if (fHWViewport != viewport) { | 2667 if (fHWViewport != viewport) { |
| 2663 viewport.pushToGLViewport(this->glInterface()); | 2668 viewport.pushToGLViewport(this->glInterface()); |
| 2664 fHWViewport = viewport; | 2669 fHWViewport = viewport; |
| 2665 } | 2670 } |
| 2666 } | 2671 } |
| 2667 | 2672 |
| 2668 GrGLenum gPrimitiveType2GLMode[] = { | 2673 GrGLenum gPrimitiveType2GLMode[] = { |
| 2669 GR_GL_TRIANGLES, | 2674 GR_GL_TRIANGLES, |
| 2670 GR_GL_TRIANGLE_STRIP, | 2675 GR_GL_TRIANGLE_STRIP, |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3131 this->setTextureUnit(unitIdx); | 3136 this->setTextureUnit(unitIdx); |
| 3132 GL_CALL(BindTexture(target, texture->textureID())); | 3137 GL_CALL(BindTexture(target, texture->textureID())); |
| 3133 fHWBoundTextureUniqueIDs[unitIdx] = textureID; | 3138 fHWBoundTextureUniqueIDs[unitIdx] = textureID; |
| 3134 } | 3139 } |
| 3135 | 3140 |
| 3136 ResetTimestamp timestamp; | 3141 ResetTimestamp timestamp; |
| 3137 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti mestamp); | 3142 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti mestamp); |
| 3138 bool setAll = timestamp < this->getResetTimestamp(); | 3143 bool setAll = timestamp < this->getResetTimestamp(); |
| 3139 GrGLTexture::TexParams newTexParams; | 3144 GrGLTexture::TexParams newTexParams; |
| 3140 | 3145 |
| 3141 if (this->caps()->srgbSupport()) { | |
| 3142 // By default, the decision to allow SRGB decode is based on the destina tion config. | |
| 3143 // A texture can override that by specifying a value in GrTextureParams. | |
| 3144 newTexParams.fSRGBDecode = allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SK IP_DECODE_EXT; | |
| 3145 | |
| 3146 if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) { | |
| 3147 this->setTextureUnit(unitIdx); | |
| 3148 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexP arams.fSRGBDecode)); | |
| 3149 } | |
| 3150 } | |
| 3151 | |
| 3152 static GrGLenum glMinFilterModes[] = { | 3146 static GrGLenum glMinFilterModes[] = { |
| 3153 GR_GL_NEAREST, | 3147 GR_GL_NEAREST, |
| 3154 GR_GL_LINEAR, | 3148 GR_GL_LINEAR, |
| 3155 GR_GL_LINEAR_MIPMAP_LINEAR | 3149 GR_GL_LINEAR_MIPMAP_LINEAR |
| 3156 }; | 3150 }; |
| 3157 static GrGLenum glMagFilterModes[] = { | 3151 static GrGLenum glMagFilterModes[] = { |
| 3158 GR_GL_NEAREST, | 3152 GR_GL_NEAREST, |
| 3159 GR_GL_LINEAR, | 3153 GR_GL_LINEAR, |
| 3160 GR_GL_LINEAR | 3154 GR_GL_LINEAR |
| 3161 }; | 3155 }; |
| 3162 GrTextureParams::FilterMode filterMode = params.filterMode(); | 3156 GrTextureParams::FilterMode filterMode = params.filterMode(); |
| 3163 | 3157 |
| 3164 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 3158 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 3165 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { | 3159 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { |
| 3166 filterMode = GrTextureParams::kBilerp_FilterMode; | 3160 filterMode = GrTextureParams::kBilerp_FilterMode; |
| 3167 } | 3161 } |
| 3168 } | 3162 } |
| 3169 | 3163 |
| 3170 newTexParams.fMinFilter = glMinFilterModes[filterMode]; | 3164 newTexParams.fMinFilter = glMinFilterModes[filterMode]; |
| 3171 newTexParams.fMagFilter = glMagFilterModes[filterMode]; | 3165 newTexParams.fMagFilter = glMagFilterModes[filterMode]; |
| 3172 | 3166 |
| 3173 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 3167 bool enableSRGBDecode = false; |
| 3174 if (texture->texturePriv().mipMapsAreDirty()) { | 3168 if (GrPixelConfigIsSRGB(texture->config())) { |
| 3169 enableSRGBDecode = allowSRGBInputs; | |
| 3170 | |
| 3171 newTexParams.fSRGBDecode = enableSRGBDecode ? GR_GL_DECODE_EXT : GR_GL_S KIP_DECODE_EXT; | |
| 3172 if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) { | |
| 3175 this->setTextureUnit(unitIdx); | 3173 this->setTextureUnit(unitIdx); |
| 3176 GL_CALL(GenerateMipmap(target)); | 3174 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexP arams.fSRGBDecode)); |
| 3177 texture->texturePriv().dirtyMipMaps(false); | |
| 3178 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount ( | |
| 3179 texture->width(), texture->height())); | |
| 3180 } | 3175 } |
| 3181 } | 3176 } |
| 3182 | 3177 |
| 3178 #ifdef SK_DEBUG | |
| 3179 // We were supposed to ensure MipMaps were up-to-date and built correctly be fore getting here. | |
| 3180 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | |
| 3181 SkASSERT(!texture->texturePriv().mipMapsAreDirty()); | |
| 3182 if (GrPixelConfigIsSRGB(texture->config())) { | |
| 3183 SkASSERT(texture->texturePriv().mipMapsAreSRGBCorrect() == enableSRG BDecode); | |
| 3184 } | |
| 3185 } | |
| 3186 #endif | |
| 3187 | |
| 3183 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); | 3188 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); |
| 3184 | 3189 |
| 3185 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 3190 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
| 3186 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 3191 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
| 3187 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz leRGBA); | 3192 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz leRGBA); |
| 3188 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { | 3193 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { |
| 3189 this->setTextureUnit(unitIdx); | 3194 this->setTextureUnit(unitIdx); |
| 3190 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa gFilter)); | 3195 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa gFilter)); |
| 3191 } | 3196 } |
| 3192 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { | 3197 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3271 get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); | 3276 get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); |
| 3272 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); | 3277 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); |
| 3273 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); | 3278 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); |
| 3274 } | 3279 } |
| 3275 | 3280 |
| 3276 buffer->setHasAttachedToTexture(); | 3281 buffer->setHasAttachedToTexture(); |
| 3277 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUni t); | 3282 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUni t); |
| 3278 } | 3283 } |
| 3279 } | 3284 } |
| 3280 | 3285 |
| 3286 void GrGLGpu::generateMipmaps(const GrTextureParams& params, bool allowSRGBInput s, | |
| 3287 GrGLTexture* texture) { | |
| 3288 SkASSERT(texture); | |
| 3289 | |
| 3290 // First, figure out if we need mips for this texture at all: | |
| 3291 GrTextureParams::FilterMode filterMode = params.filterMode(); | |
| 3292 | |
| 3293 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | |
| 3294 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture- >config())) { | |
| 3295 filterMode = GrTextureParams::kBilerp_FilterMode; | |
| 3296 } | |
| 3297 } | |
| 3298 | |
| 3299 if (GrTextureParams::kMipMap_FilterMode != filterMode) { | |
| 3300 return; | |
| 3301 } | |
| 3302 | |
| 3303 // If this is an sRGB texture and the mips were previously built the "other" way | |
| 3304 // (gamma-correct vs. not), then we need to rebuild them. We don't need to c heck for | |
| 3305 // srgbSupport - we'll *never* get an sRGB pixel config if we don't support it. | |
| 3306 if (GrPixelConfigIsSRGB(texture->config()) && | |
| 3307 allowSRGBInputs != texture->texturePriv().mipMapsAreSRGBCorrect()) { | |
| 3308 texture->texturePriv().dirtyMipMaps(true); | |
| 3309 } | |
| 3310 | |
| 3311 // If the mips aren't dirty, we're done: | |
| 3312 if (!texture->texturePriv().mipMapsAreDirty()) { | |
| 3313 return; | |
| 3314 } | |
| 3315 | |
| 3316 // If we created a rt/tex and rendered to it without using a texture and now we're texturing | |
| 3317 // from the rt it will still be the last bound texture, but it needs resolvi ng. | |
| 3318 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTa rget()); | |
| 3319 if (texRT) { | |
| 3320 this->onResolveRenderTarget(texRT); | |
| 3321 } | |
| 3322 | |
| 3323 GrGLenum target = texture->target(); | |
| 3324 this->setScratchTextureUnit(); | |
| 3325 GL_CALL(BindTexture(target, texture->textureID())); | |
| 3326 | |
| 3327 // Configure sRGB decode, if necessary. This state is the only thing needed for the driver | |
| 3328 // call (glGenerateMipmap) to work correctly. Our manual method dirties othe r state, too. | |
| 3329 if (GrPixelConfigIsSRGB(texture->config())) { | |
| 3330 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, | |
| 3331 allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DE CODE_EXT)); | |
| 3332 } | |
| 3333 | |
| 3334 // Either do manual mipmap generation or (if that fails), just rely on the d river: | |
| 3335 if (!this->generateMipmap(texture, allowSRGBInputs)) { | |
| 3336 GL_CALL(GenerateMipmap(target)); | |
| 3337 } | |
| 3338 | |
| 3339 texture->texturePriv().dirtyMipMaps(false, allowSRGBInputs); | |
| 3340 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount( | |
| 3341 texture->width(), texture->height())); | |
| 3342 | |
| 3343 // We have potentially set lots of state on the texture. Easiest to dirty it all: | |
| 3344 texture->textureParamsModified(); | |
| 3345 } | |
| 3346 | |
| 3281 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swi zzle[]) { | 3347 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swi zzle[]) { |
| 3282 this->setTextureUnit(unitIdx); | 3348 this->setTextureUnit(unitIdx); |
| 3283 if (this->glStandard() == kGLES_GrGLStandard) { | 3349 if (this->glStandard() == kGLES_GrGLStandard) { |
| 3284 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. | 3350 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. |
| 3285 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); | 3351 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); |
| 3286 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); | 3352 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); |
| 3287 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); | 3353 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); |
| 3288 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); | 3354 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); |
| 3289 } else { | 3355 } else { |
| 3290 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); | 3356 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4061 dstGLRect.fBottom, | 4127 dstGLRect.fBottom, |
| 4062 dstGLRect.fLeft + dstGLRect.fWidth, | 4128 dstGLRect.fLeft + dstGLRect.fWidth, |
| 4063 dstGLRect.fBottom + dstGLRect.fHeight, | 4129 dstGLRect.fBottom + dstGLRect.fHeight, |
| 4064 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 4130 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
| 4065 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); | 4131 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); |
| 4066 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); | 4132 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); |
| 4067 this->didWriteToSurface(dst, &dstRect); | 4133 this->didWriteToSurface(dst, &dstRect); |
| 4068 return true; | 4134 return true; |
| 4069 } | 4135 } |
| 4070 | 4136 |
| 4137 bool gManualMipmaps = true; | |
| 4138 | |
| 4139 // Manual implementation of glGenerateMipmap, to work around driver bugs w/sRGB | |
| 4140 // Uses glBlitFramebuffer to do a series of downsample operations to successive mips. | |
| 4141 bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { | |
| 4142 // Global switch for manual mipmap generation: | |
| 4143 if (!gManualMipmaps) { | |
| 4144 return false; | |
| 4145 } | |
| 4146 | |
| 4147 // We only handle 2D textures for now: | |
|
bsalomon
2016/05/31 16:35:03
Do we need to check the format? (for renderability
Brian Osman
2016/05/31 17:33:05
Yes.
| |
| 4148 if (GR_GL_TEXTURE_2D != texture->target()) { | |
| 4149 return false; | |
| 4150 } | |
| 4151 | |
| 4152 // Our iterative downsample requires the ability to limit which level we're sampling: | |
| 4153 if (!this->glCaps().mipMapLevelAndLodControlSupport()) { | |
| 4154 return false; | |
| 4155 } | |
| 4156 | |
| 4157 // Get and bind program: | |
| 4158 int progIdx = TextureTargetToCopyProgramIdx(texture->target()); | |
| 4159 if (!fCopyPrograms[progIdx].fProgram) { | |
| 4160 if (!this->createCopyProgram(progIdx)) { | |
| 4161 SkDebugf("Failed to create copy program.\n"); | |
| 4162 return false; | |
| 4163 } | |
| 4164 } | |
| 4165 GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); | |
| 4166 fHWProgramID = fCopyPrograms[progIdx].fProgram; | |
| 4167 | |
| 4168 int width = texture->width(); | |
| 4169 int height = texture->height(); | |
| 4170 int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1; | |
| 4171 | |
| 4172 // Define all mips, if we haven't previously done so: | |
| 4173 if (0 == texture->texturePriv().maxMipMapLevel()) { | |
| 4174 GrGLenum internalFormat; | |
| 4175 GrGLenum externalFormat; | |
| 4176 GrGLenum externalType; | |
| 4177 if (!this->glCaps().getTexImageFormats(texture->desc().fConfig, texture- >desc().fConfig, | |
| 4178 &internalFormat, &externalFormat, &externalType)) { | |
| 4179 return false; | |
| 4180 } | |
| 4181 | |
| 4182 for (GrGLint level = 1; level < levelCount; ++level) { | |
| 4183 // Define the next mip: | |
|
bsalomon
2016/05/31 16:35:03
Aren't we supposed to round up the odds?
bsalomon
2016/05/31 16:38:41
Err, duh, withdrawn.
| |
| 4184 width = SkTMax(1, width / 2); | |
| 4185 height = SkTMax(1, height / 2); | |
| 4186 GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, leve l, internalFormat, | |
| 4187 width, height, 0, | |
| 4188 externalFormat, extern alType, nullptr)); | |
| 4189 } | |
| 4190 } | |
| 4191 | |
| 4192 // Create (if necessary), then bind temporary FBO: | |
| 4193 if (0 == fTempDstFBOID) { | |
| 4194 GL_CALL(GenFramebuffers(1, &fTempDstFBOID)); | |
| 4195 } | |
| 4196 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID)); | |
| 4197 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
| 4198 | |
| 4199 // Turn FB sRGB on or off: | |
| 4200 if (this->glCaps().srgbWriteControl()) { | |
| 4201 this->setFramebufferSRGB(gammaCorrect); | |
| 4202 } | |
| 4203 | |
| 4204 // Bind the texture, to get things basically configured. We'll be mucking wi th state further. | |
| 4205 this->setTextureUnit(0); | |
|
bsalomon
2016/05/31 16:35:03
I think we have some notion of a scratch texture u
Brian Osman
2016/05/31 17:33:05
We do, although the index of that unit isn't a sim
bsalomon
2016/05/31 19:45:46
sgtm
| |
| 4206 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F ilterMode); | |
| 4207 this->bindTexture(0, params, gammaCorrect, texture); | |
| 4208 | |
| 4209 // Vertex data: | |
| 4210 fHWVertexArrayState.setVertexArrayID(this, 0); | |
| 4211 | |
| 4212 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray( this); | |
| 4213 attribs->set(this, 0, fCopyProgramArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), | |
| 4214 0); | |
| 4215 attribs->disableUnusedArrays(this, 0x1); | |
| 4216 | |
| 4217 // Set "simple" state once: | |
| 4218 GrXferProcessor::BlendInfo blendInfo; | |
| 4219 blendInfo.reset(); | |
| 4220 this->flushBlend(blendInfo, GrSwizzle::RGBA()); | |
| 4221 this->flushColorWrite(true); | |
| 4222 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | |
| 4223 this->flushHWAAState(nullptr, false, false); | |
| 4224 this->disableScissor(); | |
| 4225 GrStencilSettings stencil; | |
| 4226 stencil.setDisabled(); | |
| 4227 this->flushStencil(stencil); | |
| 4228 | |
| 4229 // Configure rects to always map entire previous mip to next mip: | |
| 4230 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, 2.0f, 2.0f, -1.0f , -1.0f)); | |
| 4231 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform, 1.0f, 1.0f, 0.0f, 0.0f)); | |
| 4232 GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0)); | |
| 4233 | |
| 4234 // Do all the blits: | |
| 4235 width = texture->width(); | |
| 4236 height = texture->height(); | |
| 4237 GrGLIRect viewport; | |
| 4238 viewport.fLeft = 0; | |
| 4239 viewport.fBottom = 0; | |
| 4240 for (GrGLint level = 1; level < levelCount; ++level) { | |
| 4241 // Only sample from previous mip | |
| 4242 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1)); | |
| 4243 | |
| 4244 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, | |
| 4245 GR_GL_TEXTURE_2D, texture->textureID(), lev el)); | |
| 4246 | |
| 4247 width = SkTMax(1, width / 2); | |
| 4248 height = SkTMax(1, height / 2); | |
| 4249 viewport.fWidth = width; | |
| 4250 viewport.fHeight = height; | |
| 4251 this->flushViewport(viewport); | |
| 4252 | |
| 4253 GrGLenum status; | |
| 4254 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); | |
| 4255 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | |
| 4256 SkDebugf("FB status: 0x%08x\n", status); | |
| 4257 } | |
| 4258 | |
| 4259 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); | |
| 4260 } | |
| 4261 | |
| 4262 // Unbind: | |
| 4263 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, | |
| 4264 GR_GL_TEXTURE_2D, 0, 0)); | |
| 4265 this->didWriteToSurface(texture, nullptr, levelCount); | |
|
bsalomon
2016/05/31 16:35:03
Do we need this? IIRC we use this to track whether
Brian Osman
2016/05/31 17:33:05
Ah, true. I was basing this off the copySurfaceAsX
| |
| 4266 | |
| 4267 return true; | |
| 4268 } | |
| 4269 | |
| 4071 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, | 4270 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, |
| 4072 const GrStencilSettings& stencil, | 4271 const GrStencilSettings& stencil, |
| 4073 int* effectiveSampleCnt, | 4272 int* effectiveSampleCnt, |
| 4074 SkAutoTDeleteArray<SkPoint>* sampleLocations ) { | 4273 SkAutoTDeleteArray<SkPoint>* sampleLocations ) { |
| 4075 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme nt() || | 4274 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme nt() || |
| 4076 stencil.isDisabled()); | 4275 stencil.isDisabled()); |
| 4077 | 4276 |
| 4078 this->flushStencil(stencil); | 4277 this->flushStencil(stencil); |
| 4079 this->flushHWAAState(rt, true, !stencil.isDisabled()); | 4278 this->flushHWAAState(rt, true, !stencil.isDisabled()); |
| 4080 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyI Rect()); | 4279 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyI Rect()); |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4245 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || | 4444 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
| 4246 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4445 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
| 4247 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4446 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
| 4248 copyParams->fWidth = texture->width(); | 4447 copyParams->fWidth = texture->width(); |
| 4249 copyParams->fHeight = texture->height(); | 4448 copyParams->fHeight = texture->height(); |
| 4250 return true; | 4449 return true; |
| 4251 } | 4450 } |
| 4252 } | 4451 } |
| 4253 return false; | 4452 return false; |
| 4254 } | 4453 } |
| OLD | NEW |