Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(509)

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

Issue 2007973002: Manually generated sRGB mipmaps. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Cleanup of write-control and bindTexture logic Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLProgram.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/gpu/gl/GrGLGpu.h ('k') | src/gpu/gl/GrGLProgram.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698