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 this->flushFramebufferSRGB(GrPixelConfigIsSRGB(target->config()) && !dis ableSRGB); |
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::flushFramebufferSRGB(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. | |
bsalomon
2016/05/31 19:45:46
Perhaps here we should just assert that the they'r
Brian Osman
2016/06/01 13:24:58
That's all the code below is doing. (Plus the seco
bsalomon
2016/06/01 15:41:28
Oh duh
| |
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. | |
bsalomon
2016/05/31 19:45:46
comment is out of date
Maybe say that if this ret
Brian Osman
2016/06/01 13:24:58
Done.
| |
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: | |
4148 if (GR_GL_TEXTURE_2D != texture->target()) { | |
4149 return false; | |
4150 } | |
4151 | |
4152 // We need to be able to render to the texture for this to work: | |
4153 if (this->caps()->isConfigRenderable(texture->config(), false)) { | |
4154 return false; | |
4155 } | |
4156 | |
4157 // Our iterative downsample requires the ability to limit which level we're sampling: | |
4158 if (!this->glCaps().mipMapLevelAndLodControlSupport()) { | |
4159 return false; | |
4160 } | |
4161 | |
4162 // Get and bind program: | |
4163 int progIdx = TextureTargetToCopyProgramIdx(texture->target()); | |
4164 if (!fCopyPrograms[progIdx].fProgram) { | |
4165 if (!this->createCopyProgram(progIdx)) { | |
4166 SkDebugf("Failed to create copy program.\n"); | |
4167 return false; | |
4168 } | |
4169 } | |
4170 GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); | |
4171 fHWProgramID = fCopyPrograms[progIdx].fProgram; | |
4172 | |
4173 int width = texture->width(); | |
4174 int height = texture->height(); | |
4175 int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1; | |
4176 | |
4177 // Define all mips, if we haven't previously done so: | |
4178 if (0 == texture->texturePriv().maxMipMapLevel()) { | |
4179 GrGLenum internalFormat; | |
4180 GrGLenum externalFormat; | |
4181 GrGLenum externalType; | |
4182 if (!this->glCaps().getTexImageFormats(texture->config(), texture->confi g(), | |
4183 &internalFormat, &externalFormat, &externalType)) { | |
4184 return false; | |
4185 } | |
4186 | |
4187 for (GrGLint level = 1; level < levelCount; ++level) { | |
4188 // Define the next mip: | |
4189 width = SkTMax(1, width / 2); | |
4190 height = SkTMax(1, height / 2); | |
4191 GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, leve l, internalFormat, | |
4192 width, height, 0, | |
4193 externalFormat, extern alType, nullptr)); | |
4194 } | |
4195 } | |
4196 | |
4197 // Create (if necessary), then bind temporary FBO: | |
4198 if (0 == fTempDstFBOID) { | |
4199 GL_CALL(GenFramebuffers(1, &fTempDstFBOID)); | |
4200 } | |
4201 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID)); | |
4202 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; | |
4203 | |
4204 // Turn FB sRGB on or off: | |
4205 if (this->glCaps().srgbWriteControl()) { | |
4206 this->flushFramebufferSRGB(gammaCorrect); | |
4207 } | |
4208 | |
4209 // Bind the texture, to get things configured for filtering. | |
4210 // We'll be changing our base level further below: | |
4211 this->setTextureUnit(0); | |
4212 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F ilterMode); | |
4213 this->bindTexture(0, params, gammaCorrect, texture); | |
4214 | |
4215 // Vertex data: | |
4216 fHWVertexArrayState.setVertexArrayID(this, 0); | |
4217 | |
4218 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray( this); | |
4219 attribs->set(this, 0, fCopyProgramArrayBuffer, kVec2f_GrVertexAttribType, 2 * sizeof(GrGLfloat), | |
4220 0); | |
4221 attribs->disableUnusedArrays(this, 0x1); | |
4222 | |
4223 // Set "simple" state once: | |
4224 GrXferProcessor::BlendInfo blendInfo; | |
4225 blendInfo.reset(); | |
4226 this->flushBlend(blendInfo, GrSwizzle::RGBA()); | |
4227 this->flushColorWrite(true); | |
4228 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); | |
4229 this->flushHWAAState(nullptr, false, false); | |
4230 this->disableScissor(); | |
4231 GrStencilSettings stencil; | |
4232 stencil.setDisabled(); | |
4233 this->flushStencil(stencil); | |
4234 | |
4235 // Configure rects to always map entire previous mip to next mip: | |
4236 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, 2.0f, 2.0f, -1.0f , -1.0f)); | |
4237 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform, 1.0f, 1.0f, 0.0f, 0.0f)); | |
4238 GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0)); | |
4239 | |
4240 // Do all the blits: | |
4241 width = texture->width(); | |
4242 height = texture->height(); | |
4243 GrGLIRect viewport; | |
4244 viewport.fLeft = 0; | |
4245 viewport.fBottom = 0; | |
4246 for (GrGLint level = 1; level < levelCount; ++level) { | |
4247 // Only sample from previous mip | |
4248 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level - 1)); | |
4249 | |
4250 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, | |
4251 GR_GL_TEXTURE_2D, texture->textureID(), lev el)); | |
4252 | |
4253 width = SkTMax(1, width / 2); | |
4254 height = SkTMax(1, height / 2); | |
4255 viewport.fWidth = width; | |
4256 viewport.fHeight = height; | |
4257 this->flushViewport(viewport); | |
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 | |
4266 return true; | |
4267 } | |
4268 | |
4071 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, | 4269 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, |
4072 const GrStencilSettings& stencil, | 4270 const GrStencilSettings& stencil, |
4073 int* effectiveSampleCnt, | 4271 int* effectiveSampleCnt, |
4074 SkAutoTDeleteArray<SkPoint>* sampleLocations ) { | 4272 SkAutoTDeleteArray<SkPoint>* sampleLocations ) { |
4075 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme nt() || | 4273 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme nt() || |
4076 stencil.isDisabled()); | 4274 stencil.isDisabled()); |
4077 | 4275 |
4078 this->flushStencil(stencil); | 4276 this->flushStencil(stencil); |
4079 this->flushHWAAState(rt, true, !stencil.isDisabled()); | 4277 this->flushHWAAState(rt, true, !stencil.isDisabled()); |
4080 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyI Rect()); | 4278 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() || | 4443 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
4246 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4444 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
4247 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4445 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
4248 copyParams->fWidth = texture->width(); | 4446 copyParams->fWidth = texture->width(); |
4249 copyParams->fHeight = texture->height(); | 4447 copyParams->fHeight = texture->height(); |
4250 return true; | 4448 return true; |
4251 } | 4449 } |
4252 } | 4450 } |
4253 return false; | 4451 return false; |
4254 } | 4452 } |
OLD | NEW |