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
); |
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 (!this->glCaps().srgbWriteControl()) { |
| 2658 return; |
| 2659 } |
| 2660 |
| 2661 if (enable && kYes_TriState != fHWSRGBFramebuffer) { |
| 2662 GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB)); |
| 2663 fHWSRGBFramebuffer = kYes_TriState; |
| 2664 } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) { |
| 2665 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); |
| 2666 fHWSRGBFramebuffer = kNo_TriState; |
| 2667 } |
| 2668 } |
| 2669 |
2661 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { | 2670 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { |
2662 if (fHWViewport != viewport) { | 2671 if (fHWViewport != viewport) { |
2663 viewport.pushToGLViewport(this->glInterface()); | 2672 viewport.pushToGLViewport(this->glInterface()); |
2664 fHWViewport = viewport; | 2673 fHWViewport = viewport; |
2665 } | 2674 } |
2666 } | 2675 } |
2667 | 2676 |
2668 GrGLenum gPrimitiveType2GLMode[] = { | 2677 GrGLenum gPrimitiveType2GLMode[] = { |
2669 GR_GL_TRIANGLES, | 2678 GR_GL_TRIANGLES, |
2670 GR_GL_TRIANGLE_STRIP, | 2679 GR_GL_TRIANGLE_STRIP, |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 this->setTextureUnit(unitIdx); | 3140 this->setTextureUnit(unitIdx); |
3132 GL_CALL(BindTexture(target, texture->textureID())); | 3141 GL_CALL(BindTexture(target, texture->textureID())); |
3133 fHWBoundTextureUniqueIDs[unitIdx] = textureID; | 3142 fHWBoundTextureUniqueIDs[unitIdx] = textureID; |
3134 } | 3143 } |
3135 | 3144 |
3136 ResetTimestamp timestamp; | 3145 ResetTimestamp timestamp; |
3137 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti
mestamp); | 3146 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti
mestamp); |
3138 bool setAll = timestamp < this->getResetTimestamp(); | 3147 bool setAll = timestamp < this->getResetTimestamp(); |
3139 GrGLTexture::TexParams newTexParams; | 3148 GrGLTexture::TexParams newTexParams; |
3140 | 3149 |
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[] = { | 3150 static GrGLenum glMinFilterModes[] = { |
3153 GR_GL_NEAREST, | 3151 GR_GL_NEAREST, |
3154 GR_GL_LINEAR, | 3152 GR_GL_LINEAR, |
3155 GR_GL_LINEAR_MIPMAP_LINEAR | 3153 GR_GL_LINEAR_MIPMAP_LINEAR |
3156 }; | 3154 }; |
3157 static GrGLenum glMagFilterModes[] = { | 3155 static GrGLenum glMagFilterModes[] = { |
3158 GR_GL_NEAREST, | 3156 GR_GL_NEAREST, |
3159 GR_GL_LINEAR, | 3157 GR_GL_LINEAR, |
3160 GR_GL_LINEAR | 3158 GR_GL_LINEAR |
3161 }; | 3159 }; |
3162 GrTextureParams::FilterMode filterMode = params.filterMode(); | 3160 GrTextureParams::FilterMode filterMode = params.filterMode(); |
3163 | 3161 |
3164 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 3162 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
3165 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { | 3163 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { |
3166 filterMode = GrTextureParams::kBilerp_FilterMode; | 3164 filterMode = GrTextureParams::kBilerp_FilterMode; |
3167 } | 3165 } |
3168 } | 3166 } |
3169 | 3167 |
3170 newTexParams.fMinFilter = glMinFilterModes[filterMode]; | 3168 newTexParams.fMinFilter = glMinFilterModes[filterMode]; |
3171 newTexParams.fMagFilter = glMagFilterModes[filterMode]; | 3169 newTexParams.fMagFilter = glMagFilterModes[filterMode]; |
3172 | 3170 |
| 3171 bool enableSRGBDecode = false; |
| 3172 if (GrPixelConfigIsSRGB(texture->config())) { |
| 3173 enableSRGBDecode = allowSRGBInputs; |
| 3174 |
| 3175 newTexParams.fSRGBDecode = enableSRGBDecode ? GR_GL_DECODE_EXT : GR_GL_S
KIP_DECODE_EXT; |
| 3176 if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) { |
| 3177 this->setTextureUnit(unitIdx); |
| 3178 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, newTexP
arams.fSRGBDecode)); |
| 3179 } |
| 3180 |
| 3181 // If we're going to be using MipMaps, and they were last built with sRG
B decode in the |
| 3182 // wrong state, then mark them as dirty so we will re-run GenerateMipmap
below... |
| 3183 // TODO: Remove this code, shouldn't be necessary. |
| 3184 if (GrTextureParams::kMipMap_FilterMode == filterMode && |
| 3185 texture->texturePriv().mipMapsAreSRGBCorrect() != enableSRGBDecode)
{ |
| 3186 texture->texturePriv().dirtyMipMaps(true); |
| 3187 } |
| 3188 } |
| 3189 |
3173 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 3190 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
3174 if (texture->texturePriv().mipMapsAreDirty()) { | 3191 if (texture->texturePriv().mipMapsAreDirty()) { |
| 3192 SkDebugf("Mip maps are dirty in bindTexture. Shouldn't happen.\n"); |
3175 this->setTextureUnit(unitIdx); | 3193 this->setTextureUnit(unitIdx); |
3176 GL_CALL(GenerateMipmap(target)); | 3194 GL_CALL(GenerateMipmap(target)); |
3177 texture->texturePriv().dirtyMipMaps(false); | 3195 texture->texturePriv().dirtyMipMaps(false, enableSRGBDecode); |
3178 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount
( | 3196 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount
( |
3179 texture->width(), texture->height())); | 3197 texture->width(), texture->height())); |
3180 } | 3198 } |
3181 } | 3199 } |
3182 | 3200 |
3183 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); | 3201 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); |
3184 | 3202 |
3185 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 3203 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
3186 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 3204 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
3187 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz
leRGBA); | 3205 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz
leRGBA); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3271 get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); | 3289 get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); |
3272 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); | 3290 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); |
3273 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); | 3291 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); |
3274 } | 3292 } |
3275 | 3293 |
3276 buffer->setHasAttachedToTexture(); | 3294 buffer->setHasAttachedToTexture(); |
3277 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUni
t); | 3295 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUni
t); |
3278 } | 3296 } |
3279 } | 3297 } |
3280 | 3298 |
| 3299 void GrGLGpu::generateMipmaps(const GrTextureParams& params, bool allowSRGBInput
s, |
| 3300 GrGLTexture* texture) { |
| 3301 SkASSERT(texture); |
| 3302 |
| 3303 // First, figure out if we need mips for this texture at all: |
| 3304 GrTextureParams::FilterMode filterMode = params.filterMode(); |
| 3305 |
| 3306 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 3307 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { |
| 3308 filterMode = GrTextureParams::kBilerp_FilterMode; |
| 3309 } |
| 3310 } |
| 3311 |
| 3312 if (GrTextureParams::kMipMap_FilterMode != filterMode) { |
| 3313 return; |
| 3314 } |
| 3315 |
| 3316 // If this is an sRGB texture and the mips were previously built the "other"
way |
| 3317 // (gamma-correct vs. not), then we need to rebuild them. We don't need to c
heck for |
| 3318 // srgbSupport - we'll *never* get an sRGB pixel config if we don't support
it. |
| 3319 if (GrPixelConfigIsSRGB(texture->config()) && |
| 3320 allowSRGBInputs != texture->texturePriv().mipMapsAreSRGBCorrect()) { |
| 3321 texture->texturePriv().dirtyMipMaps(true); |
| 3322 } |
| 3323 |
| 3324 // If the mips aren't dirty, we're done: |
| 3325 if (!texture->texturePriv().mipMapsAreDirty()) { |
| 3326 return; |
| 3327 } |
| 3328 |
| 3329 // If we created a rt/tex and rendered to it without using a texture and now
we're texturing |
| 3330 // from the rt it will still be the last bound texture, but it needs resolvi
ng. |
| 3331 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTa
rget()); |
| 3332 if (texRT) { |
| 3333 this->onResolveRenderTarget(texRT); |
| 3334 } |
| 3335 |
| 3336 GrGLenum target = texture->target(); |
| 3337 this->setScratchTextureUnit(); |
| 3338 GL_CALL(BindTexture(target, texture->textureID())); |
| 3339 |
| 3340 // Configure sRGB decode, if necessary. This state is the only thing needed
for the driver |
| 3341 // call (glGenerateMipmap) to work correctly. Our manual method dirties othe
r state, too. |
| 3342 if (GrPixelConfigIsSRGB(texture->config())) { |
| 3343 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, |
| 3344 allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DE
CODE_EXT)); |
| 3345 } |
| 3346 |
| 3347 // Either do manual mipmap generation or (if that fails), just rely on the d
river: |
| 3348 if (!this->generateMipmap(texture, allowSRGBInputs)) { |
| 3349 GL_CALL(GenerateMipmap(target)); |
| 3350 } |
| 3351 |
| 3352 texture->texturePriv().dirtyMipMaps(false, allowSRGBInputs); |
| 3353 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount( |
| 3354 texture->width(), texture->height())); |
| 3355 |
| 3356 // We have potentially set lots of state on the texture. Easiest to dirty it
all: |
| 3357 texture->textureParamsModified(); |
| 3358 } |
| 3359 |
3281 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swi
zzle[]) { | 3360 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swi
zzle[]) { |
3282 this->setTextureUnit(unitIdx); | 3361 this->setTextureUnit(unitIdx); |
3283 if (this->glStandard() == kGLES_GrGLStandard) { | 3362 if (this->glStandard() == kGLES_GrGLStandard) { |
3284 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. | 3363 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. |
3285 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); | 3364 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); |
3286 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); | 3365 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); |
3287 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); | 3366 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); |
3288 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); | 3367 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); |
3289 } else { | 3368 } else { |
3290 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); | 3369 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4061 dstGLRect.fBottom, | 4140 dstGLRect.fBottom, |
4062 dstGLRect.fLeft + dstGLRect.fWidth, | 4141 dstGLRect.fLeft + dstGLRect.fWidth, |
4063 dstGLRect.fBottom + dstGLRect.fHeight, | 4142 dstGLRect.fBottom + dstGLRect.fHeight, |
4064 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 4143 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
4065 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); | 4144 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); |
4066 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); | 4145 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); |
4067 this->didWriteToSurface(dst, &dstRect); | 4146 this->didWriteToSurface(dst, &dstRect); |
4068 return true; | 4147 return true; |
4069 } | 4148 } |
4070 | 4149 |
| 4150 bool gManualMipmaps = true; |
| 4151 |
| 4152 // Manual implementation of glGenerateMipmap, to work around driver bugs w/sRGB |
| 4153 // Uses glBlitFramebuffer to do a series of downsample operations to successive
mips. |
| 4154 bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { |
| 4155 // Global switch for manual mipmap generation: |
| 4156 if (!gManualMipmaps) { |
| 4157 return false; |
| 4158 } |
| 4159 |
| 4160 // We only handle 2D textures for now: |
| 4161 if (GR_GL_TEXTURE_2D != texture->target()) { |
| 4162 return false; |
| 4163 } |
| 4164 |
| 4165 // Our iterative downsample requires the ability to limit which level we're
sampling: |
| 4166 if (!this->glCaps().mipMapLevelAndLodControlSupport()) { |
| 4167 return false; |
| 4168 } |
| 4169 |
| 4170 // Get and bind program: |
| 4171 int progIdx = TextureTargetToCopyProgramIdx(texture->target()); |
| 4172 if (!fCopyPrograms[progIdx].fProgram) { |
| 4173 if (!this->createCopyProgram(progIdx)) { |
| 4174 SkDebugf("Failed to create copy program.\n"); |
| 4175 return false; |
| 4176 } |
| 4177 } |
| 4178 GL_CALL(UseProgram(fCopyPrograms[progIdx].fProgram)); |
| 4179 fHWProgramID = fCopyPrograms[progIdx].fProgram; |
| 4180 |
| 4181 int width = texture->width(); |
| 4182 int height = texture->height(); |
| 4183 int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1; |
| 4184 |
| 4185 // Define all mips, if we haven't previously done so: |
| 4186 if (0 == texture->texturePriv().maxMipMapLevel()) { |
| 4187 GrGLenum internalFormat; |
| 4188 GrGLenum externalFormat; |
| 4189 GrGLenum externalType; |
| 4190 if (!this->glCaps().getTexImageFormats(texture->desc().fConfig, texture-
>desc().fConfig, |
| 4191 &internalFormat, &externalFormat,
&externalType)) { |
| 4192 return false; |
| 4193 } |
| 4194 |
| 4195 for (GrGLint level = 1; level < levelCount; ++level) { |
| 4196 // Define the next mip: |
| 4197 width = SkTMax(1, width / 2); |
| 4198 height = SkTMax(1, height / 2); |
| 4199 GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, leve
l, internalFormat, |
| 4200 width, height, 0, |
| 4201 externalFormat, extern
alType, nullptr)); |
| 4202 } |
| 4203 } |
| 4204 |
| 4205 // Create (if necessary), then bind temporary FBO: |
| 4206 if (0 == fTempDstFBOID) { |
| 4207 GL_CALL(GenFramebuffers(1, &fTempDstFBOID)); |
| 4208 } |
| 4209 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID)); |
| 4210 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 4211 |
| 4212 // Turn FB sRGB on or off: |
| 4213 this->setFramebufferSRGB(gammaCorrect); |
| 4214 |
| 4215 // Bind the texture, to get things basically configured. We'll be mucking wi
th state further. |
| 4216 this->setTextureUnit(0); |
| 4217 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F
ilterMode); |
| 4218 this->bindTexture(0, params, gammaCorrect, texture); |
| 4219 |
| 4220 // Vertex data: |
| 4221 fHWVertexArrayState.setVertexArrayID(this, 0); |
| 4222 |
| 4223 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(
this); |
| 4224 attribs->set(this, 0, fCopyProgramArrayBuffer, kVec2f_GrVertexAttribType, 2
* sizeof(GrGLfloat), |
| 4225 0); |
| 4226 attribs->disableUnusedArrays(this, 0x1); |
| 4227 |
| 4228 // Set "simple" state once: |
| 4229 GrXferProcessor::BlendInfo blendInfo; |
| 4230 blendInfo.reset(); |
| 4231 this->flushBlend(blendInfo, GrSwizzle::RGBA()); |
| 4232 this->flushColorWrite(true); |
| 4233 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
| 4234 this->flushHWAAState(nullptr, false, false); |
| 4235 this->disableScissor(); |
| 4236 GrStencilSettings stencil; |
| 4237 stencil.setDisabled(); |
| 4238 this->flushStencil(stencil); |
| 4239 |
| 4240 // Configure rects to always map entire previous mip to next mip: |
| 4241 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fPosXformUniform, 2.0f, 2.0f, -1.0f
, -1.0f)); |
| 4242 GL_CALL(Uniform4f(fCopyPrograms[progIdx].fTexCoordXformUniform, 1.0f, 1.0f,
0.0f, 0.0f)); |
| 4243 GL_CALL(Uniform1i(fCopyPrograms[progIdx].fTextureUniform, 0)); |
| 4244 |
| 4245 // Do all the blits: |
| 4246 width = texture->width(); |
| 4247 height = texture->height(); |
| 4248 GrGLIRect viewport; |
| 4249 viewport.fLeft = 0; |
| 4250 viewport.fBottom = 0; |
| 4251 for (GrGLint level = 1; level < levelCount; ++level) { |
| 4252 // Only sample from previous mip |
| 4253 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level
- 1)); |
| 4254 |
| 4255 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, |
| 4256 GR_GL_TEXTURE_2D, texture->textureID(), lev
el)); |
| 4257 |
| 4258 width = SkTMax(1, width / 2); |
| 4259 height = SkTMax(1, height / 2); |
| 4260 viewport.fWidth = width; |
| 4261 viewport.fHeight = height; |
| 4262 this->flushViewport(viewport); |
| 4263 |
| 4264 GrGLenum status; |
| 4265 GL_CALL_RET(status, CheckFramebufferStatus(GR_GL_FRAMEBUFFER)); |
| 4266 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
| 4267 SkDebugf("FB status: 0x%08x\n", status); |
| 4268 } |
| 4269 |
| 4270 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); |
| 4271 } |
| 4272 |
| 4273 // Unbind: |
| 4274 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, |
| 4275 GR_GL_TEXTURE_2D, 0, 0)); |
| 4276 this->didWriteToSurface(texture, nullptr, levelCount); |
| 4277 |
| 4278 return true; |
| 4279 } |
| 4280 |
4071 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, | 4281 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, |
4072 const GrStencilSettings& stencil, | 4282 const GrStencilSettings& stencil, |
4073 int* effectiveSampleCnt, | 4283 int* effectiveSampleCnt, |
4074 SkAutoTDeleteArray<SkPoint>* sampleLocations
) { | 4284 SkAutoTDeleteArray<SkPoint>* sampleLocations
) { |
4075 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme
nt() || | 4285 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme
nt() || |
4076 stencil.isDisabled()); | 4286 stencil.isDisabled()); |
4077 | 4287 |
4078 this->flushStencil(stencil); | 4288 this->flushStencil(stencil); |
4079 this->flushHWAAState(rt, true, !stencil.isDisabled()); | 4289 this->flushHWAAState(rt, true, !stencil.isDisabled()); |
4080 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyI
Rect()); | 4290 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() || | 4455 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
4246 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4456 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
4247 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4457 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
4248 copyParams->fWidth = texture->width(); | 4458 copyParams->fWidth = texture->width(); |
4249 copyParams->fHeight = texture->height(); | 4459 copyParams->fHeight = texture->height(); |
4250 return true; | 4460 return true; |
4251 } | 4461 } |
4252 } | 4462 } |
4253 return false; | 4463 return false; |
4254 } | 4464 } |
OLD | NEW |