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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 , fTempSrcFBOID(0) | 194 , fTempSrcFBOID(0) |
195 , fTempDstFBOID(0) | 195 , fTempDstFBOID(0) |
196 , fStencilClearFBOID(0) | 196 , fStencilClearFBOID(0) |
197 , fHWMaxUsedBufferTextureUnit(-1) | 197 , fHWMaxUsedBufferTextureUnit(-1) |
198 , fHWPLSEnabled(false) | 198 , fHWPLSEnabled(false) |
199 , fPLSHasBeenUsed(false) | 199 , fPLSHasBeenUsed(false) |
200 , fHWMinSampleShading(0.0) { | 200 , fHWMinSampleShading(0.0) { |
201 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { | 201 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
202 fCopyPrograms[i].fProgram = 0; | 202 fCopyPrograms[i].fProgram = 0; |
203 } | 203 } |
| 204 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { |
| 205 fMipmapPrograms[i].fProgram = 0; |
| 206 } |
204 fWireRectProgram.fProgram = 0; | 207 fWireRectProgram.fProgram = 0; |
205 fPLSSetupProgram.fProgram = 0; | 208 fPLSSetupProgram.fProgram = 0; |
206 | 209 |
207 SkASSERT(ctx); | 210 SkASSERT(ctx); |
208 fCaps.reset(SkRef(ctx->caps())); | 211 fCaps.reset(SkRef(ctx->caps())); |
209 | 212 |
210 fHWBoundTextureUniqueIDs.reset(this->glCaps().glslCaps()->maxCombinedSampler
s()); | 213 fHWBoundTextureUniqueIDs.reset(this->glCaps().glslCaps()->maxCombinedSampler
s()); |
211 | 214 |
212 fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER; | 215 fHWBufferState[kVertex_GrBufferType].fGLTarget = GR_GL_ARRAY_BUFFER; |
213 fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER; | 216 fHWBufferState[kIndex_GrBufferType].fGLTarget = GR_GL_ELEMENT_ARRAY_BUFFER; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 SkDebugf("\n"); | 253 SkDebugf("\n"); |
251 SkDebugf("%s", this->glCaps().dump().c_str()); | 254 SkDebugf("%s", this->glCaps().dump().c_str()); |
252 } | 255 } |
253 } | 256 } |
254 | 257 |
255 GrGLGpu::~GrGLGpu() { | 258 GrGLGpu::~GrGLGpu() { |
256 // Ensure any GrGpuResource objects get deleted first, since they may requir
e a working GrGLGpu | 259 // Ensure any GrGpuResource objects get deleted first, since they may requir
e a working GrGLGpu |
257 // to release the resources held by the objects themselves. | 260 // to release the resources held by the objects themselves. |
258 fPathRendering.reset(); | 261 fPathRendering.reset(); |
259 fCopyProgramArrayBuffer.reset(); | 262 fCopyProgramArrayBuffer.reset(); |
| 263 fMipmapProgramArrayBuffer.reset(); |
260 fWireRectArrayBuffer.reset(); | 264 fWireRectArrayBuffer.reset(); |
261 fPLSSetupProgram.fArrayBuffer.reset(); | 265 fPLSSetupProgram.fArrayBuffer.reset(); |
262 | 266 |
263 if (0 != fHWProgramID) { | 267 if (0 != fHWProgramID) { |
264 // detach the current program so there is no confusion on OpenGL's part | 268 // detach the current program so there is no confusion on OpenGL's part |
265 // that we want it to be deleted | 269 // that we want it to be deleted |
266 GL_CALL(UseProgram(0)); | 270 GL_CALL(UseProgram(0)); |
267 } | 271 } |
268 | 272 |
269 if (0 != fTempSrcFBOID) { | 273 if (0 != fTempSrcFBOID) { |
270 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); | 274 GL_CALL(DeleteFramebuffers(1, &fTempSrcFBOID)); |
271 } | 275 } |
272 if (0 != fTempDstFBOID) { | 276 if (0 != fTempDstFBOID) { |
273 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); | 277 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); |
274 } | 278 } |
275 if (0 != fStencilClearFBOID) { | 279 if (0 != fStencilClearFBOID) { |
276 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); | 280 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
277 } | 281 } |
278 | 282 |
279 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { | 283 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
280 if (0 != fCopyPrograms[i].fProgram) { | 284 if (0 != fCopyPrograms[i].fProgram) { |
281 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); | 285 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); |
282 } | 286 } |
283 } | 287 } |
284 | 288 |
| 289 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { |
| 290 if (0 != fMipmapPrograms[i].fProgram) { |
| 291 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram)); |
| 292 } |
| 293 } |
| 294 |
285 if (0 != fWireRectProgram.fProgram) { | 295 if (0 != fWireRectProgram.fProgram) { |
286 GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); | 296 GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); |
287 } | 297 } |
288 | 298 |
289 if (0 != fPLSSetupProgram.fProgram) { | 299 if (0 != fPLSSetupProgram.fProgram) { |
290 GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram)); | 300 GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram)); |
291 } | 301 } |
292 | 302 |
293 delete fProgramCache; | 303 delete fProgramCache; |
294 } | 304 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); | 424 GL_CALL(DeleteFramebuffers(1, &fTempDstFBOID)); |
415 } | 425 } |
416 if (fStencilClearFBOID) { | 426 if (fStencilClearFBOID) { |
417 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); | 427 GL_CALL(DeleteFramebuffers(1, &fStencilClearFBOID)); |
418 } | 428 } |
419 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { | 429 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
420 if (fCopyPrograms[i].fProgram) { | 430 if (fCopyPrograms[i].fProgram) { |
421 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); | 431 GL_CALL(DeleteProgram(fCopyPrograms[i].fProgram)); |
422 } | 432 } |
423 } | 433 } |
| 434 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { |
| 435 if (fMipmapPrograms[i].fProgram) { |
| 436 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram)); |
| 437 } |
| 438 } |
424 if (fWireRectProgram.fProgram) { | 439 if (fWireRectProgram.fProgram) { |
425 GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); | 440 GL_CALL(DeleteProgram(fWireRectProgram.fProgram)); |
426 } | 441 } |
427 if (fPLSSetupProgram.fProgram) { | 442 if (fPLSSetupProgram.fProgram) { |
428 GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram)); | 443 GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram)); |
429 } | 444 } |
430 } else { | 445 } else { |
431 if (fProgramCache) { | 446 if (fProgramCache) { |
432 fProgramCache->abandon(); | 447 fProgramCache->abandon(); |
433 } | 448 } |
434 } | 449 } |
435 | 450 |
436 delete fProgramCache; | 451 delete fProgramCache; |
437 fProgramCache = nullptr; | 452 fProgramCache = nullptr; |
438 | 453 |
439 fHWProgramID = 0; | 454 fHWProgramID = 0; |
440 fTempSrcFBOID = 0; | 455 fTempSrcFBOID = 0; |
441 fTempDstFBOID = 0; | 456 fTempDstFBOID = 0; |
442 fStencilClearFBOID = 0; | 457 fStencilClearFBOID = 0; |
443 fCopyProgramArrayBuffer.reset(); | 458 fCopyProgramArrayBuffer.reset(); |
444 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { | 459 for (size_t i = 0; i < SK_ARRAY_COUNT(fCopyPrograms); ++i) { |
445 fCopyPrograms[i].fProgram = 0; | 460 fCopyPrograms[i].fProgram = 0; |
446 } | 461 } |
| 462 fMipmapProgramArrayBuffer.reset(); |
| 463 for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) { |
| 464 fMipmapPrograms[i].fProgram = 0; |
| 465 } |
447 fWireRectProgram.fProgram = 0; | 466 fWireRectProgram.fProgram = 0; |
448 fWireRectArrayBuffer.reset(); | 467 fWireRectArrayBuffer.reset(); |
449 fPLSSetupProgram.fProgram = 0; | 468 fPLSSetupProgram.fProgram = 0; |
450 fPLSSetupProgram.fArrayBuffer.reset(); | 469 fPLSSetupProgram.fArrayBuffer.reset(); |
451 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { | 470 if (this->glCaps().shaderCaps()->pathRenderingSupport()) { |
452 this->glPathRendering()->disconnect(type); | 471 this->glPathRendering()->disconnect(type); |
453 } | 472 } |
454 } | 473 } |
455 | 474 |
456 /////////////////////////////////////////////////////////////////////////////// | 475 /////////////////////////////////////////////////////////////////////////////// |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1974 GL_CALL(MinSampleShading(minSampleShading)); | 1993 GL_CALL(MinSampleShading(minSampleShading)); |
1975 } | 1994 } |
1976 else { | 1995 else { |
1977 GL_CALL(Disable(GR_GL_SAMPLE_SHADING)); | 1996 GL_CALL(Disable(GR_GL_SAMPLE_SHADING)); |
1978 } | 1997 } |
1979 fHWMinSampleShading = minSampleShading; | 1998 fHWMinSampleShading = minSampleShading; |
1980 } | 1999 } |
1981 } | 2000 } |
1982 | 2001 |
1983 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
r& primProc) { | 2002 bool GrGLGpu::flushGLState(const GrPipeline& pipeline, const GrPrimitiveProcesso
r& primProc) { |
| 2003 SkAutoTUnref<GrGLProgram> program(fProgramCache->refProgram(this, pipeline,
primProc)); |
| 2004 if (!program) { |
| 2005 GrCapsDebugf(this->caps(), "Failed to create program!\n"); |
| 2006 return false; |
| 2007 } |
| 2008 |
| 2009 program->generateMipmaps(primProc, pipeline); |
| 2010 |
1984 GrXferProcessor::BlendInfo blendInfo; | 2011 GrXferProcessor::BlendInfo blendInfo; |
1985 pipeline.getXferProcessor().getBlendInfo(&blendInfo); | 2012 pipeline.getXferProcessor().getBlendInfo(&blendInfo); |
1986 | 2013 |
1987 this->flushColorWrite(blendInfo.fWriteColor); | 2014 this->flushColorWrite(blendInfo.fWriteColor); |
1988 this->flushDrawFace(pipeline.getDrawFace()); | 2015 this->flushDrawFace(pipeline.getDrawFace()); |
1989 this->flushMinSampleShading(primProc.getSampleShading()); | 2016 this->flushMinSampleShading(primProc.getSampleShading()); |
1990 | 2017 |
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(); | 2018 GrGLuint programID = program->programID(); |
1998 if (fHWProgramID != programID) { | 2019 if (fHWProgramID != programID) { |
1999 GL_CALL(UseProgram(programID)); | 2020 GL_CALL(UseProgram(programID)); |
2000 fHWProgramID = programID; | 2021 fHWProgramID = programID; |
2001 } | 2022 } |
2002 | 2023 |
2003 if (blendInfo.fWriteColor) { | 2024 if (blendInfo.fWriteColor) { |
2004 // Swizzle the blend to match what the shader will output. | 2025 // Swizzle the blend to match what the shader will output. |
2005 const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzl
e( | 2026 const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzl
e( |
2006 pipeline.getRenderTarget()->config()); | 2027 pipeline.getRenderTarget()->config()); |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2638 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { | 2659 if (status != GR_GL_FRAMEBUFFER_COMPLETE) { |
2639 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x
\n", status); | 2660 SkDebugf("GrGLGpu::flushRenderTarget glCheckFramebufferStatus %x
\n", status); |
2640 } | 2661 } |
2641 } | 2662 } |
2642 #endif | 2663 #endif |
2643 fHWBoundRenderTargetUniqueID = rtID; | 2664 fHWBoundRenderTargetUniqueID = rtID; |
2644 this->flushViewport(target->getViewport()); | 2665 this->flushViewport(target->getViewport()); |
2645 } | 2666 } |
2646 | 2667 |
2647 if (this->glCaps().srgbWriteControl()) { | 2668 if (this->glCaps().srgbWriteControl()) { |
2648 bool enableSRGBWrite = GrPixelConfigIsSRGB(target->config()) && !disable
SRGB; | 2669 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 } | 2670 } |
2657 | 2671 |
2658 this->didWriteToSurface(target, bounds); | 2672 this->didWriteToSurface(target, bounds); |
2659 } | 2673 } |
2660 | 2674 |
| 2675 void GrGLGpu::flushFramebufferSRGB(bool enable) { |
| 2676 if (enable && kYes_TriState != fHWSRGBFramebuffer) { |
| 2677 GL_CALL(Enable(GR_GL_FRAMEBUFFER_SRGB)); |
| 2678 fHWSRGBFramebuffer = kYes_TriState; |
| 2679 } else if (!enable && kNo_TriState != fHWSRGBFramebuffer) { |
| 2680 GL_CALL(Disable(GR_GL_FRAMEBUFFER_SRGB)); |
| 2681 fHWSRGBFramebuffer = kNo_TriState; |
| 2682 } |
| 2683 } |
| 2684 |
2661 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { | 2685 void GrGLGpu::flushViewport(const GrGLIRect& viewport) { |
2662 if (fHWViewport != viewport) { | 2686 if (fHWViewport != viewport) { |
2663 viewport.pushToGLViewport(this->glInterface()); | 2687 viewport.pushToGLViewport(this->glInterface()); |
2664 fHWViewport = viewport; | 2688 fHWViewport = viewport; |
2665 } | 2689 } |
2666 } | 2690 } |
2667 | 2691 |
2668 GrGLenum gPrimitiveType2GLMode[] = { | 2692 GrGLenum gPrimitiveType2GLMode[] = { |
2669 GR_GL_TRIANGLES, | 2693 GR_GL_TRIANGLES, |
2670 GR_GL_TRIANGLE_STRIP, | 2694 GR_GL_TRIANGLE_STRIP, |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 this->setTextureUnit(unitIdx); | 3155 this->setTextureUnit(unitIdx); |
3132 GL_CALL(BindTexture(target, texture->textureID())); | 3156 GL_CALL(BindTexture(target, texture->textureID())); |
3133 fHWBoundTextureUniqueIDs[unitIdx] = textureID; | 3157 fHWBoundTextureUniqueIDs[unitIdx] = textureID; |
3134 } | 3158 } |
3135 | 3159 |
3136 ResetTimestamp timestamp; | 3160 ResetTimestamp timestamp; |
3137 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti
mestamp); | 3161 const GrGLTexture::TexParams& oldTexParams = texture->getCachedTexParams(&ti
mestamp); |
3138 bool setAll = timestamp < this->getResetTimestamp(); | 3162 bool setAll = timestamp < this->getResetTimestamp(); |
3139 GrGLTexture::TexParams newTexParams; | 3163 GrGLTexture::TexParams newTexParams; |
3140 | 3164 |
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[] = { | 3165 static GrGLenum glMinFilterModes[] = { |
3153 GR_GL_NEAREST, | 3166 GR_GL_NEAREST, |
3154 GR_GL_LINEAR, | 3167 GR_GL_LINEAR, |
3155 GR_GL_LINEAR_MIPMAP_LINEAR | 3168 GR_GL_LINEAR_MIPMAP_LINEAR |
3156 }; | 3169 }; |
3157 static GrGLenum glMagFilterModes[] = { | 3170 static GrGLenum glMagFilterModes[] = { |
3158 GR_GL_NEAREST, | 3171 GR_GL_NEAREST, |
3159 GR_GL_LINEAR, | 3172 GR_GL_LINEAR, |
3160 GR_GL_LINEAR | 3173 GR_GL_LINEAR |
3161 }; | 3174 }; |
3162 GrTextureParams::FilterMode filterMode = params.filterMode(); | 3175 GrTextureParams::FilterMode filterMode = params.filterMode(); |
3163 | 3176 |
3164 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 3177 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
3165 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { | 3178 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { |
3166 filterMode = GrTextureParams::kBilerp_FilterMode; | 3179 filterMode = GrTextureParams::kBilerp_FilterMode; |
3167 } | 3180 } |
3168 } | 3181 } |
3169 | 3182 |
3170 newTexParams.fMinFilter = glMinFilterModes[filterMode]; | 3183 newTexParams.fMinFilter = glMinFilterModes[filterMode]; |
3171 newTexParams.fMagFilter = glMagFilterModes[filterMode]; | 3184 newTexParams.fMagFilter = glMagFilterModes[filterMode]; |
3172 | 3185 |
3173 if (GrTextureParams::kMipMap_FilterMode == filterMode) { | 3186 bool enableSRGBDecode = false; |
3174 if (texture->texturePriv().mipMapsAreDirty()) { | 3187 if (GrPixelConfigIsSRGB(texture->config())) { |
| 3188 enableSRGBDecode = allowSRGBInputs; |
| 3189 |
| 3190 newTexParams.fSRGBDecode = enableSRGBDecode ? GR_GL_DECODE_EXT : GR_GL_S
KIP_DECODE_EXT; |
| 3191 if (setAll || newTexParams.fSRGBDecode != oldTexParams.fSRGBDecode) { |
3175 this->setTextureUnit(unitIdx); | 3192 this->setTextureUnit(unitIdx); |
3176 GL_CALL(GenerateMipmap(target)); | 3193 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 } | 3194 } |
3181 } | 3195 } |
3182 | 3196 |
| 3197 #ifdef SK_DEBUG |
| 3198 // We were supposed to ensure MipMaps were up-to-date and built correctly be
fore getting here. |
| 3199 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 3200 SkASSERT(!texture->texturePriv().mipMapsAreDirty()); |
| 3201 if (GrPixelConfigIsSRGB(texture->config())) { |
| 3202 SkASSERT(texture->texturePriv().mipMapsAreSRGBCorrect() == enableSRG
BDecode); |
| 3203 } |
| 3204 } |
| 3205 #endif |
| 3206 |
3183 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); | 3207 newTexParams.fMaxMipMapLevel = texture->texturePriv().maxMipMapLevel(); |
3184 | 3208 |
3185 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); | 3209 newTexParams.fWrapS = tile_to_gl_wrap(params.getTileModeX()); |
3186 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); | 3210 newTexParams.fWrapT = tile_to_gl_wrap(params.getTileModeY()); |
3187 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz
leRGBA); | 3211 get_tex_param_swizzle(texture->config(), this->glCaps(), newTexParams.fSwizz
leRGBA); |
3188 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { | 3212 if (setAll || newTexParams.fMagFilter != oldTexParams.fMagFilter) { |
3189 this->setTextureUnit(unitIdx); | 3213 this->setTextureUnit(unitIdx); |
3190 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa
gFilter)); | 3214 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, newTexParams.fMa
gFilter)); |
3191 } | 3215 } |
3192 if (setAll || newTexParams.fMinFilter != oldTexParams.fMinFilter) { | 3216 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); | 3295 get_tex_param_swizzle(texelConfig, this->glCaps(), glSwizzle); |
3272 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); | 3296 this->setTextureSwizzle(unitIdx, GR_GL_TEXTURE_BUFFER, glSwizzle); |
3273 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); | 3297 buffTex.fSwizzle = this->glCaps().configSwizzle(texelConfig); |
3274 } | 3298 } |
3275 | 3299 |
3276 buffer->setHasAttachedToTexture(); | 3300 buffer->setHasAttachedToTexture(); |
3277 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUni
t); | 3301 fHWMaxUsedBufferTextureUnit = SkTMax(unitIdx, fHWMaxUsedBufferTextureUni
t); |
3278 } | 3302 } |
3279 } | 3303 } |
3280 | 3304 |
| 3305 void GrGLGpu::generateMipmaps(const GrTextureParams& params, bool allowSRGBInput
s, |
| 3306 GrGLTexture* texture) { |
| 3307 SkASSERT(texture); |
| 3308 |
| 3309 // First, figure out if we need mips for this texture at all: |
| 3310 GrTextureParams::FilterMode filterMode = params.filterMode(); |
| 3311 |
| 3312 if (GrTextureParams::kMipMap_FilterMode == filterMode) { |
| 3313 if (!this->caps()->mipMapSupport() || GrPixelConfigIsCompressed(texture-
>config())) { |
| 3314 filterMode = GrTextureParams::kBilerp_FilterMode; |
| 3315 } |
| 3316 } |
| 3317 |
| 3318 if (GrTextureParams::kMipMap_FilterMode != filterMode) { |
| 3319 return; |
| 3320 } |
| 3321 |
| 3322 // If this is an sRGB texture and the mips were previously built the "other"
way |
| 3323 // (gamma-correct vs. not), then we need to rebuild them. We don't need to c
heck for |
| 3324 // srgbSupport - we'll *never* get an sRGB pixel config if we don't support
it. |
| 3325 if (GrPixelConfigIsSRGB(texture->config()) && |
| 3326 allowSRGBInputs != texture->texturePriv().mipMapsAreSRGBCorrect()) { |
| 3327 texture->texturePriv().dirtyMipMaps(true); |
| 3328 } |
| 3329 |
| 3330 // If the mips aren't dirty, we're done: |
| 3331 if (!texture->texturePriv().mipMapsAreDirty()) { |
| 3332 return; |
| 3333 } |
| 3334 |
| 3335 // If we created a rt/tex and rendered to it without using a texture and now
we're texturing |
| 3336 // from the rt it will still be the last bound texture, but it needs resolvi
ng. |
| 3337 GrGLRenderTarget* texRT = static_cast<GrGLRenderTarget*>(texture->asRenderTa
rget()); |
| 3338 if (texRT) { |
| 3339 this->onResolveRenderTarget(texRT); |
| 3340 } |
| 3341 |
| 3342 GrGLenum target = texture->target(); |
| 3343 this->setScratchTextureUnit(); |
| 3344 GL_CALL(BindTexture(target, texture->textureID())); |
| 3345 |
| 3346 // Configure sRGB decode, if necessary. This state is the only thing needed
for the driver |
| 3347 // call (glGenerateMipmap) to work correctly. Our manual method dirties othe
r state, too. |
| 3348 if (GrPixelConfigIsSRGB(texture->config())) { |
| 3349 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SRGB_DECODE_EXT, |
| 3350 allowSRGBInputs ? GR_GL_DECODE_EXT : GR_GL_SKIP_DE
CODE_EXT)); |
| 3351 } |
| 3352 |
| 3353 // Either do manual mipmap generation or (if that fails), just rely on the d
river: |
| 3354 if (!this->generateMipmap(texture, allowSRGBInputs)) { |
| 3355 GL_CALL(GenerateMipmap(target)); |
| 3356 } |
| 3357 |
| 3358 texture->texturePriv().dirtyMipMaps(false, allowSRGBInputs); |
| 3359 texture->texturePriv().setMaxMipMapLevel(SkMipMap::ComputeLevelCount( |
| 3360 texture->width(), texture->height())); |
| 3361 |
| 3362 // We have potentially set lots of state on the texture. Easiest to dirty it
all: |
| 3363 texture->textureParamsModified(); |
| 3364 } |
| 3365 |
3281 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swi
zzle[]) { | 3366 void GrGLGpu::setTextureSwizzle(int unitIdx, GrGLenum target, const GrGLenum swi
zzle[]) { |
3282 this->setTextureUnit(unitIdx); | 3367 this->setTextureUnit(unitIdx); |
3283 if (this->glStandard() == kGLES_GrGLStandard) { | 3368 if (this->glStandard() == kGLES_GrGLStandard) { |
3284 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. | 3369 // ES3 added swizzle support but not GL_TEXTURE_SWIZZLE_RGBA. |
3285 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); | 3370 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_R, swizzle[0])); |
3286 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); | 3371 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_G, swizzle[1])); |
3287 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); | 3372 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_B, swizzle[2])); |
3288 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); | 3373 GL_CALL(TexParameteri(target, GR_GL_TEXTURE_SWIZZLE_A, swizzle[3])); |
3289 } else { | 3374 } else { |
3290 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); | 3375 GR_STATIC_ASSERT(sizeof(swizzle[0]) == sizeof(GrGLint)); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3704 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordX
form")); | 3789 GetUniformLocation(fCopyPrograms[progIdx].fProgram, "u_texCoordX
form")); |
3705 | 3790 |
3706 GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex")); | 3791 GL_CALL(BindAttribLocation(fCopyPrograms[progIdx].fProgram, 0, "a_vertex")); |
3707 | 3792 |
3708 GL_CALL(DeleteShader(vshader)); | 3793 GL_CALL(DeleteShader(vshader)); |
3709 GL_CALL(DeleteShader(fshader)); | 3794 GL_CALL(DeleteShader(fshader)); |
3710 | 3795 |
3711 return true; | 3796 return true; |
3712 } | 3797 } |
3713 | 3798 |
| 3799 bool GrGLGpu::createMipmapProgram(int progIdx) { |
| 3800 const bool oddWidth = SkToBool(progIdx & 0x2); |
| 3801 const bool oddHeight = SkToBool(progIdx & 0x1); |
| 3802 const int numTaps = (oddWidth ? 2 : 1) * (oddHeight ? 2 : 1); |
| 3803 |
| 3804 const GrGLSLCaps* glslCaps = this->glCaps().glslCaps(); |
| 3805 |
| 3806 SkASSERT(!fMipmapPrograms[progIdx].fProgram); |
| 3807 GL_CALL_RET(fMipmapPrograms[progIdx].fProgram, CreateProgram()); |
| 3808 if (!fMipmapPrograms[progIdx].fProgram) { |
| 3809 return false; |
| 3810 } |
| 3811 |
| 3812 const char* version = glslCaps->versionDeclString(); |
| 3813 GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute
_TypeModifier); |
| 3814 GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType, |
| 3815 GrShaderVar::kUniform_TypeModifier); |
| 3816 GrGLSLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUni
form_TypeModifier); |
| 3817 // We need 1, 2, or 4 texture coordinates (depending on parity of each dimen
sion): |
| 3818 GrGLSLShaderVar vTexCoords[] = { |
| 3819 GrGLSLShaderVar("v_texCoord0", kVec2f_GrSLType, GrShaderVar::kVaryingOut
_TypeModifier), |
| 3820 GrGLSLShaderVar("v_texCoord1", kVec2f_GrSLType, GrShaderVar::kVaryingOut
_TypeModifier), |
| 3821 GrGLSLShaderVar("v_texCoord2", kVec2f_GrSLType, GrShaderVar::kVaryingOut
_TypeModifier), |
| 3822 GrGLSLShaderVar("v_texCoord3", kVec2f_GrSLType, GrShaderVar::kVaryingOut
_TypeModifier), |
| 3823 }; |
| 3824 GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, |
| 3825 GrShaderVar::kOut_TypeModifier); |
| 3826 |
| 3827 SkString vshaderTxt(version); |
| 3828 if (glslCaps->noperspectiveInterpolationSupport()) { |
| 3829 if (const char* extension = glslCaps->noperspectiveInterpolationExtensio
nString()) { |
| 3830 vshaderTxt.appendf("#extension %s : require\n", extension); |
| 3831 } |
| 3832 vTexCoords[0].addModifier("noperspective"); |
| 3833 vTexCoords[1].addModifier("noperspective"); |
| 3834 vTexCoords[2].addModifier("noperspective"); |
| 3835 vTexCoords[3].addModifier("noperspective"); |
| 3836 } |
| 3837 |
| 3838 aVertex.appendDecl(glslCaps, &vshaderTxt); |
| 3839 vshaderTxt.append(";"); |
| 3840 uTexCoordXform.appendDecl(glslCaps, &vshaderTxt); |
| 3841 vshaderTxt.append(";"); |
| 3842 for (int i = 0; i < numTaps; ++i) { |
| 3843 vTexCoords[i].appendDecl(glslCaps, &vshaderTxt); |
| 3844 vshaderTxt.append(";"); |
| 3845 } |
| 3846 |
| 3847 vshaderTxt.append( |
| 3848 "// Mipmap Program VS\n" |
| 3849 "void main() {" |
| 3850 " gl_Position.xy = a_vertex * vec2(2, 2) - vec2(1, 1);" |
| 3851 " gl_Position.zw = vec2(0, 1);" |
| 3852 ); |
| 3853 |
| 3854 // Insert texture coordinate computation: |
| 3855 if (oddWidth && oddHeight) { |
| 3856 vshaderTxt.append( |
| 3857 " v_texCoord0 = a_vertex.xy * u_texCoordXform.yw;" |
| 3858 " v_texCoord1 = a_vertex.xy * u_texCoordXform.yw + vec2(u_texCoordX
form.x, 0);" |
| 3859 " v_texCoord2 = a_vertex.xy * u_texCoordXform.yw + vec2(0, u_texCoo
rdXform.z);" |
| 3860 " v_texCoord3 = a_vertex.xy * u_texCoordXform.yw + u_texCoordXform.
xz;" |
| 3861 ); |
| 3862 } else if (oddWidth) { |
| 3863 vshaderTxt.append( |
| 3864 " v_texCoord0 = a_vertex.xy * vec2(u_texCoordXform.y, 1);" |
| 3865 " v_texCoord1 = a_vertex.xy * vec2(u_texCoordXform.y, 1) + vec2(u_t
exCoordXform.x, 0);" |
| 3866 ); |
| 3867 } else if (oddHeight) { |
| 3868 vshaderTxt.append( |
| 3869 " v_texCoord0 = a_vertex.xy * vec2(1, u_texCoordXform.w);" |
| 3870 " v_texCoord1 = a_vertex.xy * vec2(1, u_texCoordXform.w) + vec2(0,
u_texCoordXform.z);" |
| 3871 ); |
| 3872 } else { |
| 3873 vshaderTxt.append( |
| 3874 " v_texCoord0 = a_vertex.xy;" |
| 3875 ); |
| 3876 } |
| 3877 |
| 3878 vshaderTxt.append("}"); |
| 3879 |
| 3880 SkString fshaderTxt(version); |
| 3881 if (glslCaps->noperspectiveInterpolationSupport()) { |
| 3882 if (const char* extension = glslCaps->noperspectiveInterpolationExtensio
nString()) { |
| 3883 fshaderTxt.appendf("#extension %s : require\n", extension); |
| 3884 } |
| 3885 } |
| 3886 GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *glslCa
ps, |
| 3887 &fshaderTxt); |
| 3888 for (int i = 0; i < numTaps; ++i) { |
| 3889 vTexCoords[i].setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier); |
| 3890 vTexCoords[i].appendDecl(glslCaps, &fshaderTxt); |
| 3891 fshaderTxt.append(";"); |
| 3892 } |
| 3893 uTexture.appendDecl(glslCaps, &fshaderTxt); |
| 3894 fshaderTxt.append(";"); |
| 3895 const char* fsOutName; |
| 3896 if (glslCaps->mustDeclareFragmentShaderOutput()) { |
| 3897 oFragColor.appendDecl(glslCaps, &fshaderTxt); |
| 3898 fshaderTxt.append(";"); |
| 3899 fsOutName = oFragColor.c_str(); |
| 3900 } else { |
| 3901 fsOutName = "gl_FragColor"; |
| 3902 } |
| 3903 const char* sampleFunction = GrGLSLTexture2DFunctionName(kVec2f_GrSLType, kS
ampler2D_GrSLType, |
| 3904 this->glslGeneratio
n()); |
| 3905 fshaderTxt.append( |
| 3906 "// Mipmap Program FS\n" |
| 3907 "void main() {" |
| 3908 ); |
| 3909 |
| 3910 if (oddWidth && oddHeight) { |
| 3911 fshaderTxt.appendf( |
| 3912 " %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1) + " |
| 3913 " %s(u_texture, v_texCoord2) + %s(u_texture, v_texCoord3)) *
0.25;", |
| 3914 fsOutName, sampleFunction, sampleFunction, sampleFunction, sampleFun
ction |
| 3915 ); |
| 3916 } else if (oddWidth || oddHeight) { |
| 3917 fshaderTxt.appendf( |
| 3918 " %s = (%s(u_texture, v_texCoord0) + %s(u_texture, v_texCoord1)) *
0.5;", |
| 3919 fsOutName, sampleFunction, sampleFunction |
| 3920 ); |
| 3921 } else { |
| 3922 fshaderTxt.appendf( |
| 3923 " %s = %s(u_texture, v_texCoord0);", |
| 3924 fsOutName, sampleFunction |
| 3925 ); |
| 3926 } |
| 3927 |
| 3928 fshaderTxt.append("}"); |
| 3929 |
| 3930 const char* str; |
| 3931 GrGLint length; |
| 3932 |
| 3933 str = vshaderTxt.c_str(); |
| 3934 length = SkToInt(vshaderTxt.size()); |
| 3935 GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[p
rogIdx].fProgram, |
| 3936 GR_GL_VERTEX_SHADER, &str, &le
ngth, 1, |
| 3937 &fStats); |
| 3938 |
| 3939 str = fshaderTxt.c_str(); |
| 3940 length = SkToInt(fshaderTxt.size()); |
| 3941 GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fMipmapPrograms[p
rogIdx].fProgram, |
| 3942 GR_GL_FRAGMENT_SHADER, &str, &
length, 1, |
| 3943 &fStats); |
| 3944 |
| 3945 GL_CALL(LinkProgram(fMipmapPrograms[progIdx].fProgram)); |
| 3946 |
| 3947 GL_CALL_RET(fMipmapPrograms[progIdx].fTextureUniform, |
| 3948 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texture
")); |
| 3949 GL_CALL_RET(fMipmapPrograms[progIdx].fTexCoordXformUniform, |
| 3950 GetUniformLocation(fMipmapPrograms[progIdx].fProgram, "u_texCoor
dXform")); |
| 3951 |
| 3952 GL_CALL(BindAttribLocation(fMipmapPrograms[progIdx].fProgram, 0, "a_vertex")
); |
| 3953 |
| 3954 GL_CALL(DeleteShader(vshader)); |
| 3955 GL_CALL(DeleteShader(fshader)); |
| 3956 |
| 3957 return true; |
| 3958 } |
| 3959 |
3714 bool GrGLGpu::createWireRectProgram() { | 3960 bool GrGLGpu::createWireRectProgram() { |
3715 if (!fWireRectArrayBuffer) { | 3961 if (!fWireRectArrayBuffer) { |
3716 static const GrGLfloat vdata[] = { | 3962 static const GrGLfloat vdata[] = { |
3717 0, 0, | 3963 0, 0, |
3718 0, 1, | 3964 0, 1, |
3719 1, 1, | 3965 1, 1, |
3720 1, 0 | 3966 1, 0 |
3721 }; | 3967 }; |
3722 fWireRectArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVert
ex_GrBufferType, | 3968 fWireRectArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVert
ex_GrBufferType, |
3723 kStatic_GrAccessPattern, v
data)); | 3969 kStatic_GrAccessPattern, v
data)); |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4061 dstGLRect.fBottom, | 4307 dstGLRect.fBottom, |
4062 dstGLRect.fLeft + dstGLRect.fWidth, | 4308 dstGLRect.fLeft + dstGLRect.fWidth, |
4063 dstGLRect.fBottom + dstGLRect.fHeight, | 4309 dstGLRect.fBottom + dstGLRect.fHeight, |
4064 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); | 4310 GR_GL_COLOR_BUFFER_BIT, GR_GL_NEAREST)); |
4065 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); | 4311 this->unbindTextureFBOForCopy(GR_GL_DRAW_FRAMEBUFFER, dst); |
4066 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); | 4312 this->unbindTextureFBOForCopy(GR_GL_READ_FRAMEBUFFER, src); |
4067 this->didWriteToSurface(dst, &dstRect); | 4313 this->didWriteToSurface(dst, &dstRect); |
4068 return true; | 4314 return true; |
4069 } | 4315 } |
4070 | 4316 |
| 4317 bool gManualMipmaps = true; |
| 4318 |
| 4319 // Manual implementation of mipmap generation, to work around driver bugs w/sRGB
. |
| 4320 // Uses draw calls to do a series of downsample operations to successive mips. |
| 4321 // If this returns false, then the calling code falls back to using glGenerateMi
pmap. |
| 4322 bool GrGLGpu::generateMipmap(GrGLTexture* texture, bool gammaCorrect) { |
| 4323 // Global switch for manual mipmap generation: |
| 4324 if (!gManualMipmaps) { |
| 4325 return false; |
| 4326 } |
| 4327 |
| 4328 // Mipmaps are only supported on 2D textures: |
| 4329 if (GR_GL_TEXTURE_2D != texture->target()) { |
| 4330 return false; |
| 4331 } |
| 4332 |
| 4333 // We need to be able to render to the texture for this to work: |
| 4334 if (!this->caps()->isConfigRenderable(texture->config(), false)) { |
| 4335 return false; |
| 4336 } |
| 4337 |
| 4338 // Our iterative downsample requires the ability to limit which level we're
sampling: |
| 4339 if (!this->glCaps().mipMapLevelAndLodControlSupport()) { |
| 4340 return false; |
| 4341 } |
| 4342 |
| 4343 // If we're mipping an sRGB texture, we need to ensure FB sRGB is correct: |
| 4344 if (GrPixelConfigIsSRGB(texture->config())) { |
| 4345 // If we have write-control, just set the state that we want: |
| 4346 if (this->glCaps().srgbWriteControl()) { |
| 4347 this->flushFramebufferSRGB(gammaCorrect); |
| 4348 } else if (!gammaCorrect) { |
| 4349 // If we don't have write-control we can't do non-gamma-correct mipm
apping: |
| 4350 return false; |
| 4351 } |
| 4352 } |
| 4353 |
| 4354 int width = texture->width(); |
| 4355 int height = texture->height(); |
| 4356 int levelCount = SkMipMap::ComputeLevelCount(width, height) + 1; |
| 4357 |
| 4358 // Define all mips, if we haven't previously done so: |
| 4359 if (0 == texture->texturePriv().maxMipMapLevel()) { |
| 4360 GrGLenum internalFormat; |
| 4361 GrGLenum externalFormat; |
| 4362 GrGLenum externalType; |
| 4363 if (!this->glCaps().getTexImageFormats(texture->config(), texture->confi
g(), |
| 4364 &internalFormat, &externalFormat,
&externalType)) { |
| 4365 return false; |
| 4366 } |
| 4367 |
| 4368 for (GrGLint level = 1; level < levelCount; ++level) { |
| 4369 // Define the next mip: |
| 4370 width = SkTMax(1, width / 2); |
| 4371 height = SkTMax(1, height / 2); |
| 4372 GL_ALLOC_CALL(this->glInterface(), TexImage2D(GR_GL_TEXTURE_2D, leve
l, internalFormat, |
| 4373 width, height, 0, |
| 4374 externalFormat, extern
alType, nullptr)); |
| 4375 } |
| 4376 } |
| 4377 |
| 4378 // Create (if necessary), then bind temporary FBO: |
| 4379 if (0 == fTempDstFBOID) { |
| 4380 GL_CALL(GenFramebuffers(1, &fTempDstFBOID)); |
| 4381 } |
| 4382 GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fTempDstFBOID)); |
| 4383 fHWBoundRenderTargetUniqueID = SK_InvalidUniqueID; |
| 4384 |
| 4385 // Bind the texture, to get things configured for filtering. |
| 4386 // We'll be changing our base level further below: |
| 4387 this->setTextureUnit(0); |
| 4388 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F
ilterMode); |
| 4389 this->bindTexture(0, params, gammaCorrect, texture); |
| 4390 |
| 4391 // Vertex data: |
| 4392 if (!fMipmapProgramArrayBuffer) { |
| 4393 static const GrGLfloat vdata[] = { |
| 4394 0, 0, |
| 4395 0, 1, |
| 4396 1, 0, |
| 4397 1, 1 |
| 4398 }; |
| 4399 fMipmapProgramArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), |
| 4400 kVertex_GrBufferType, |
| 4401 kStatic_GrAccessPatte
rn, vdata)); |
| 4402 } |
| 4403 if (!fMipmapProgramArrayBuffer) { |
| 4404 return false; |
| 4405 } |
| 4406 |
| 4407 fHWVertexArrayState.setVertexArrayID(this, 0); |
| 4408 |
| 4409 GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(
this); |
| 4410 attribs->set(this, 0, fMipmapProgramArrayBuffer, kVec2f_GrVertexAttribType, |
| 4411 2 * sizeof(GrGLfloat), 0); |
| 4412 attribs->disableUnusedArrays(this, 0x1); |
| 4413 |
| 4414 // Set "simple" state once: |
| 4415 GrXferProcessor::BlendInfo blendInfo; |
| 4416 blendInfo.reset(); |
| 4417 this->flushBlend(blendInfo, GrSwizzle::RGBA()); |
| 4418 this->flushColorWrite(true); |
| 4419 this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace); |
| 4420 this->flushHWAAState(nullptr, false, false); |
| 4421 this->disableScissor(); |
| 4422 GrStencilSettings stencil; |
| 4423 stencil.setDisabled(); |
| 4424 this->flushStencil(stencil); |
| 4425 |
| 4426 // Do all the blits: |
| 4427 width = texture->width(); |
| 4428 height = texture->height(); |
| 4429 GrGLIRect viewport; |
| 4430 viewport.fLeft = 0; |
| 4431 viewport.fBottom = 0; |
| 4432 for (GrGLint level = 1; level < levelCount; ++level) { |
| 4433 // Get and bind the program for this particular downsample (filter shape
can vary): |
| 4434 int progIdx = TextureSizeToMipmapProgramIdx(width, height); |
| 4435 if (!fMipmapPrograms[progIdx].fProgram) { |
| 4436 if (!this->createMipmapProgram(progIdx)) { |
| 4437 SkDebugf("Failed to create mipmap program.\n"); |
| 4438 return false; |
| 4439 } |
| 4440 } |
| 4441 GL_CALL(UseProgram(fMipmapPrograms[progIdx].fProgram)); |
| 4442 fHWProgramID = fMipmapPrograms[progIdx].fProgram; |
| 4443 |
| 4444 // Texcoord uniform is expected to contain (1/w, (w-1)/w, 1/h, (h-1)/h) |
| 4445 const float invWidth = 1.0f / width; |
| 4446 const float invHeight = 1.0f / height; |
| 4447 GL_CALL(Uniform4f(fMipmapPrograms[progIdx].fTexCoordXformUniform, |
| 4448 invWidth, (width - 1) * invWidth, invHeight, (height -
1) * invHeight)); |
| 4449 GL_CALL(Uniform1i(fMipmapPrograms[progIdx].fTextureUniform, 0)); |
| 4450 |
| 4451 // Only sample from previous mip |
| 4452 GL_CALL(TexParameteri(GR_GL_TEXTURE_2D, GR_GL_TEXTURE_BASE_LEVEL, level
- 1)); |
| 4453 |
| 4454 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, |
| 4455 GR_GL_TEXTURE_2D, texture->textureID(), lev
el)); |
| 4456 |
| 4457 width = SkTMax(1, width / 2); |
| 4458 height = SkTMax(1, height / 2); |
| 4459 viewport.fWidth = width; |
| 4460 viewport.fHeight = height; |
| 4461 this->flushViewport(viewport); |
| 4462 |
| 4463 GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4)); |
| 4464 } |
| 4465 |
| 4466 // Unbind: |
| 4467 GL_CALL(FramebufferTexture2D(GR_GL_FRAMEBUFFER, GR_GL_COLOR_ATTACHMENT0, |
| 4468 GR_GL_TEXTURE_2D, 0, 0)); |
| 4469 |
| 4470 return true; |
| 4471 } |
| 4472 |
4071 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, | 4473 void GrGLGpu::onGetMultisampleSpecs(GrRenderTarget* rt, |
4072 const GrStencilSettings& stencil, | 4474 const GrStencilSettings& stencil, |
4073 int* effectiveSampleCnt, | 4475 int* effectiveSampleCnt, |
4074 SkAutoTDeleteArray<SkPoint>* sampleLocations
) { | 4476 SkAutoTDeleteArray<SkPoint>* sampleLocations
) { |
4075 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme
nt() || | 4477 SkASSERT(!rt->hasMixedSamples() || rt->renderTargetPriv().getStencilAttachme
nt() || |
4076 stencil.isDisabled()); | 4478 stencil.isDisabled()); |
4077 | 4479 |
4078 this->flushStencil(stencil); | 4480 this->flushStencil(stencil); |
4079 this->flushHWAAState(rt, true, !stencil.isDisabled()); | 4481 this->flushHWAAState(rt, true, !stencil.isDisabled()); |
4080 this->flushRenderTarget(static_cast<GrGLRenderTarget*>(rt), &SkIRect::EmptyI
Rect()); | 4482 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() || | 4647 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
4246 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4648 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
4247 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4649 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
4248 copyParams->fWidth = texture->width(); | 4650 copyParams->fWidth = texture->width(); |
4249 copyParams->fHeight = texture->height(); | 4651 copyParams->fHeight = texture->height(); |
4250 return true; | 4652 return true; |
4251 } | 4653 } |
4252 } | 4654 } |
4253 return false; | 4655 return false; |
4254 } | 4656 } |
OLD | NEW |