From cddaf340f1474cc1ff429b8ef9bc8739c72f80ba Mon Sep 17 00:00:00 2001 From: "bsalomon@google.com" Date: Mon, 30 Jul 2012 13:09:05 +0000 Subject: [PATCH] Remove GrDrawState::setTexture/getTexture Review URL: http://codereview.appspot.com/6455051/ git-svn-id: http://skia.googlecode.com/svn/trunk@4826 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/gpu/GrSamplerState.h | 2 +- src/gpu/GrContext.cpp | 2 - src/gpu/GrDrawState.h | 67 ++--------------- src/gpu/GrDrawTarget.cpp | 46 +++++++----- src/gpu/gl/GrGLProgram.cpp | 6 +- src/gpu/gl/GrGLProgram.h | 6 +- src/gpu/gl/GrGpuGL.cpp | 5 +- src/gpu/gl/GrGpuGL.h | 4 +- src/gpu/gl/GrGpuGL_program.cpp | 156 +++++++++++++++++----------------------- src/gpu/gl/GrGpuGL_unittest.cpp | 11 +-- 10 files changed, 118 insertions(+), 187 deletions(-) diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h index 04fbe00..dcd5b66 100644 --- a/include/gpu/GrSamplerState.h +++ b/include/gpu/GrSamplerState.h @@ -179,7 +179,7 @@ public: GrSafeAssign(fCustomStage, stage); return stage; } - GrCustomStage* getCustomStage() const { return fCustomStage; } + const GrCustomStage* getCustomStage() const { return fCustomStage; } private: GrTextureParams fTextureParams; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 8e3fb09..0815562 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1552,7 +1552,6 @@ void GrContext::setPaint(const GrPaint& paint) { for (int i = 0; i < GrPaint::kMaxTextures; ++i) { int s = i + GrPaint::kFirstTextureStage; if (paint.isTextureStageEnabled(i)) { - fDrawState->setTexture(s, NULL); *fDrawState->sampler(s) = paint.getTextureSampler(i); } } @@ -1562,7 +1561,6 @@ void GrContext::setPaint(const GrPaint& paint) { for (int i = 0; i < GrPaint::kMaxMasks; ++i) { int s = i + GrPaint::kFirstMaskStage; if (paint.isMaskStageEnabled(i)) { - fDrawState->setTexture(s, NULL); *fDrawState->sampler(s) = paint.getMaskSampler(i); } } diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 471ae1c..0d81019 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -52,20 +52,12 @@ public: GrDrawState() : fRenderTarget(NULL) { - for (int i = 0; i < kNumStages; ++i) { - fTextures[i] = NULL; - } - this->reset(); } GrDrawState(const GrDrawState& state) : fRenderTarget(NULL) { - for (int i = 0; i < kNumStages; ++i) { - fTextures[i] = NULL; - } - *this = state; } @@ -109,8 +101,8 @@ public: // are tightly packed GrAssert(this->memsetSize() + sizeof(fColor) + sizeof(fCoverage) + sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) + - sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(fTextures) + - sizeof(fRenderTarget) == this->podSize()); + sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(fRenderTarget) == + this->podSize()); } /////////////////////////////////////////////////////////////////////////// @@ -182,25 +174,7 @@ public: //// /** - * Sets the texture used at the next drawing call - * - * @param stage The texture stage for which the texture will be set - * - * @param texture The texture to set. Can be NULL though there is no - * advantage to settings a NULL texture if doing non-textured drawing - * - * @deprecated - */ - void setTexture(int stage, GrTexture* texture) { - GrAssert((unsigned)stage < kNumStages); - - GrSafeAssign(fTextures[stage], texture); - } - - /** * Creates a GrSingleTextureEffect. - * - * Replacement for setTexture. */ void createTextureEffect(int stage, GrTexture* texture) { GrAssert(!this->getSampler(stage).getCustomStage()); @@ -208,38 +182,9 @@ public: SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); } - /** - * Retrieves the currently set texture. - * - * @return The currently set texture. The return value will be NULL if no - * texture has been set, NULL was most recently passed to - * setTexture, or the last setTexture was destroyed. - */ - const GrTexture* getTexture(int stage) const { - GrAssert((unsigned)stage < kNumStages); - GrAssert(!this->getSampler(stage).getCustomStage() || - !fTextures[stage] || - fTextures[stage] == this->getSampler(stage).getCustomStage()->texture(0)); - if (this->getSampler(stage).getCustomStage()) { - return this->getSampler(stage).getCustomStage()->texture(0); - } - return fTextures[stage]; - } - GrTexture* getTexture(int stage) { - GrAssert((unsigned)stage < kNumStages); - GrAssert(!this->getSampler(stage).getCustomStage() || - !fTextures[stage] || - fTextures[stage] == this->getSampler(stage).getCustomStage()->texture(0)); - if (this->getSampler(stage).getCustomStage()) { - return this->getSampler(stage).getCustomStage()->texture(0); - } - return fTextures[stage]; - } - bool stagesDisabled() { for (int i = 0; i < kNumStages; ++i) { - if (NULL != fTextures[i] || - NULL != fSamplerStates[i].getCustomStage()) { + if (NULL != fSamplerStates[i].getCustomStage()) { return false; } } @@ -247,7 +192,6 @@ public: } void disableStage(int index) { - GrSafeSetNull(fTextures[index]); fSamplerStates[index].setCustomStage(NULL); } @@ -809,8 +753,7 @@ public: bool isStageEnabled(int s) const { GrAssert((unsigned)s < kNumStages); - return (NULL != fTextures[s]) || - (NULL != fSamplerStates[s].getCustomStage()); + return (NULL != fSamplerStates[s].getCustomStage()); } // Most stages are usually not used, so conditionals here @@ -853,7 +796,6 @@ public: fViewMatrix = s.fViewMatrix; for (int i = 0; i < kNumStages; i++) { - SkSafeRef(fTextures[i]); // already copied by memcpy if (s.isStageEnabled(i)) { this->fSamplerStates[i] = s.fSamplerStates[i]; } @@ -905,7 +847,6 @@ private: // @{ Initialized to values other than zero, but memcmp'ed in operator== // and memcpy'ed in operator=. - GrTexture* fTextures[kNumStages]; GrRenderTarget* fRenderTarget; int fFirstCoverageStage; diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 8afe5b9..f0f1864 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -707,6 +707,7 @@ void GrDrawTarget::popGeometrySource() { bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, int startIndex, int vertexCount, int indexCount) const { + const GrDrawState& drawState = this->getDrawState(); #if GR_DEBUG const GeometrySrcState& geoSrc = fGeoSrcStateStack.back(); int maxVertex = startVertex + vertexCount; @@ -744,15 +745,18 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, } } - GrAssert(NULL != this->getDrawState().getRenderTarget()); - for (int i = 0; i < GrDrawState::kNumStages; ++i) { - if (this->getDrawState().getTexture(i)) { - GrAssert(this->getDrawState().getTexture(i)->asRenderTarget() != - this->getDrawState().getRenderTarget()); + GrAssert(NULL != drawState.getRenderTarget()); + for (int s = 0; s < GrDrawState::kNumStages; ++s) { + if (drawState.isStageEnabled(s)) { + const GrCustomStage* stage = drawState.getSampler(s).getCustomStage(); + int numTextures = stage->numTextures(); + for (int t = 0; t < numTextures; ++t) { + GrTexture* texture = stage->texture(t); + GrAssert(texture->asRenderTarget() != drawState.getRenderTarget()); + } } } #endif - const GrDrawState& drawState = this->getDrawState(); if (NULL == drawState.getRenderTarget()) { return false; } @@ -762,15 +766,21 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex, return false; } } + // We don't support using unpremultiplied textures with bilerp. Alpha-multiplication is not + // distributive with respect to filtering. We'd have to alpha-mul each texel before filtering. + // Until Skia itself supports unpremultiplied configs there is no pressure to implement this. for (int s = 0; s < GrDrawState::kNumStages; ++s) { - // We don't support using unpremultiplied textures with bilerp. Alpha-multiplication is not - // distributive with respect to filtering. We'd have to alpha-mul each texel before - // filtering. Until Skia itself supports unpremultiplied configs there is no pressure to - // implement this. - if (drawState.getTexture(s) && - GrPixelConfigIsUnpremultiplied(drawState.getTexture(s)->config()) && - drawState.getSampler(s).getTextureParams().isBilerp()) { - return false; + if (drawState.isStageEnabled(s)) { + const GrCustomStage* stage = drawState.getSampler(s).getCustomStage(); + int numTextures = stage->numTextures(); + for (int t = 0; t < numTextures; ++t) { + GrTexture* texture = stage->texture(t); + GrAssert(NULL != texture); + if (GrPixelConfigIsUnpremultiplied(texture->config()) && + drawState.getSampler(s).getTextureParams().isBilerp()) { + return false; + } + } } } return true; @@ -844,9 +854,11 @@ bool GrDrawTarget::srcAlphaWillBeOne(GrVertexLayout layout) const { // Check if a color stage could create a partial alpha for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) { if (this->isStageEnabled(s)) { - GrAssert(NULL != drawState.getTexture(s)); - GrPixelConfig config = drawState.getTexture(s)->config(); - if (!GrPixelConfigIsOpaque(config)) { + const GrCustomStage* stage = drawState.getSampler(s).getCustomStage(); + // FIXME: The param indicates whether the texture is opaque or not. However, the stage + // already controls its textures. It really needs to know whether the incoming color + // (from a uni, per-vertex colors, or previous stage) is opaque or not. + if (!stage->isOpaque(true)) { return false; } } diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 90ef27a..ec68eae 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -67,7 +67,7 @@ inline const char* dual_source_output_name() { return "dualSourceOut"; } GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl, const Desc& desc, - GrCustomStage** customStages) { + const GrCustomStage** customStages) { GrGLProgram* program = SkNEW_ARGS(GrGLProgram, (gl, desc, customStages)); if (!program->succeeded()) { delete program; @@ -78,7 +78,7 @@ GrGLProgram* GrGLProgram::Create(const GrGLContextInfo& gl, GrGLProgram::GrGLProgram(const GrGLContextInfo& gl, const Desc& desc, - GrCustomStage** customStages) + const GrCustomStage** customStages) : fContextInfo(gl) , fUniformManager(gl) { fDesc = desc; @@ -566,7 +566,7 @@ bool GrGLProgram::compileShaders(const GrGLShaderBuilder& builder) { return true; } -bool GrGLProgram::genProgram(GrCustomStage** customStages) { +bool GrGLProgram::genProgram(const GrCustomStage** customStages) { GrAssert(0 == fProgramID); GrGLShaderBuilder builder(fContextInfo, fUniformManager); diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index 02cb6ef..b6c224c 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -43,7 +43,7 @@ public: static GrGLProgram* Create(const GrGLContextInfo& gl, const Desc& desc, - GrCustomStage** customStages); + const GrCustomStage** customStages); virtual ~GrGLProgram(); @@ -235,14 +235,14 @@ public: private: GrGLProgram(const GrGLContextInfo& gl, const Desc& desc, - GrCustomStage** customStages); + const GrCustomStage** customStages); bool succeeded() const { return 0 != fProgramID; } /** * This is the heavy initilization routine for building a GLProgram. */ - bool genProgram(GrCustomStage** customStages); + bool genProgram(const GrCustomStage** customStages); void genInputColor(GrGLShaderBuilder* builder, SkString* inColor); diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 79ea706..68f7a9a 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -2135,8 +2135,9 @@ const GrGLenum tile_to_gl_wrap(SkShader::TileMode tm) { void GrGpuGL::flushBoundTextureAndParams(int stage) { GrDrawState* drawState = this->drawState(); - - GrGLTexture* nextTexture = static_cast(drawState->getTexture(stage)); + // FIXME: Assuming one texture maximum per custom stage + const GrCustomStage* customStage = drawState->sampler(stage)->getCustomStage(); + GrGLTexture* nextTexture = static_cast(customStage->texture(0)); // Currently we always use the texture params from the GrSamplerState. Soon custom stages // will provide their own params. const GrTextureParams& texParams = drawState->getSampler(stage).getTextureParams(); diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 2e338a1..ae19b2e 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -170,7 +170,7 @@ private: ProgramCache(const GrGLContextInfo& gl); void abandon(); - GrGLProgram* getProgram(const GrGLProgram::Desc& desc, GrCustomStage** stages); + GrGLProgram* getProgram(const GrGLProgram::Desc& desc, const GrCustomStage** stages); private: enum { kKeySize = sizeof(ProgramDesc), @@ -252,7 +252,7 @@ private: void buildProgram(bool isPoints, BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, - GrCustomStage** customStages, + const GrCustomStage** customStages, ProgramDesc* desc); // Inits GrDrawTarget::Caps, sublcass may enable additional caps. diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index d874672..b492fd4 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -32,7 +32,8 @@ void GrGpuGL::ProgramCache::abandon() { fCount = 0; } -GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc, GrCustomStage** stages) { +GrGLProgram* GrGpuGL::ProgramCache::getProgram(const ProgramDesc& desc, + const GrCustomStage** stages) { Entry newEntry; newEntry.fKey.setKeyData(desc.asKey()); @@ -195,8 +196,10 @@ bool GrGpuGL::TextureMatrixIsIdentity(const GrGLTexture* texture, void GrGpuGL::flushTextureMatrix(int s) { const GrDrawState& drawState = this->getDrawState(); - const GrGLTexture* texture = - static_cast(drawState.getTexture(s)); + + // FIXME: Still assuming only a single texture per custom stage + const GrCustomStage* stage = drawState.getSampler(s).getCustomStage(); + const GrGLTexture* texture = static_cast(stage->texture(0)); if (NULL != texture) { bool orientationChange = fCurrentProgram->fTextureOrientation[s] != @@ -370,7 +373,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { return false; } - GrCustomStage* customStages [GrDrawState::kNumStages]; + const GrCustomStage* customStages [GrDrawState::kNumStages]; GrGLProgram::Desc desc; this->buildProgram(kDrawPoints_DrawType == type, blendOpts, dstCoeff, customStages, &desc); @@ -405,21 +408,12 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (this->isStageEnabled(s)) { -#if GR_DEBUG - // check for circular rendering - GrAssert(NULL == drawState.getRenderTarget() || - NULL == drawState.getTexture(s) || - drawState.getTexture(s)->asRenderTarget() != - drawState.getRenderTarget()); -#endif this->flushBoundTextureAndParams(s); this->flushTextureMatrix(s); if (NULL != fCurrentProgram->fProgramStage[s]) { const GrSamplerState& sampler = this->getDrawState().getSampler(s); - const GrGLTexture* texture = static_cast( - this->getDrawState().getTexture(s)); fCurrentProgram->fProgramStage[s]->setData(fCurrentProgram->fUniformManager, *sampler.getCustomStage(), drawState.getRenderTarget(), s); @@ -601,9 +595,9 @@ namespace { void setup_custom_stage(GrGLProgram::Desc::StageDesc* stage, const GrSamplerState& sampler, - GrCustomStage** customStages, + const GrCustomStage** customStages, GrGLProgram* program, int index) { - GrCustomStage* customStage = sampler.getCustomStage(); + const GrCustomStage* customStage = sampler.getCustomStage(); if (customStage) { const GrProgramStageFactory& factory = customStage->getFactory(); stage->fCustomStageKey = factory.glStageKey(*customStage); @@ -619,7 +613,7 @@ void setup_custom_stage(GrGLProgram::Desc::StageDesc* stage, void GrGpuGL::buildProgram(bool isPoints, BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, - GrCustomStage** customStages, + const GrCustomStage** customStages, ProgramDesc* desc) { const GrDrawState& drawState = this->getDrawState(); @@ -641,11 +635,10 @@ void GrGpuGL::buildProgram(bool isPoints, desc->fEmitsPointSize = isPoints; - bool requiresAttributeColors = - !skipColor && SkToBool(desc->fVertexLayout & kColor_VertexLayoutBit); - bool requiresAttributeCoverage = - !skipCoverage && SkToBool(desc->fVertexLayout & - kCoverage_VertexLayoutBit); + bool requiresAttributeColors = !skipColor && + SkToBool(desc->fVertexLayout & kColor_VertexLayoutBit); + bool requiresAttributeCoverage = !skipCoverage && + SkToBool(desc->fVertexLayout & kCoverage_VertexLayoutBit); // fColorInput/fCoverageInput records how colors are specified for the. // program. So we strip the bits from the layout to avoid false negatives @@ -661,14 +654,12 @@ void GrGpuGL::buildProgram(bool isPoints, // no reason to do edge aa or look at per-vertex coverage if coverage is // ignored if (skipCoverage) { - desc->fVertexLayout &= ~(kEdge_VertexLayoutBit | - kCoverage_VertexLayoutBit); + desc->fVertexLayout &= ~(kEdge_VertexLayoutBit | kCoverage_VertexLayoutBit); } bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag); bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) || - (!requiresAttributeColors && - 0xffffffff == drawState.getColor()); + (!requiresAttributeColors && 0xffffffff == drawState.getColor()); if (GR_AGGRESSIVE_SHADER_OPTS && colorIsTransBlack) { desc->fColorInput = ProgramDesc::kTransBlack_ColorInput; } else if (GR_AGGRESSIVE_SHADER_OPTS && colorIsSolidWhite) { @@ -679,8 +670,7 @@ void GrGpuGL::buildProgram(bool isPoints, desc->fColorInput = ProgramDesc::kAttribute_ColorInput; } - bool covIsSolidWhite = !requiresAttributeCoverage && - 0xffffffff == drawState.getCoverage(); + bool covIsSolidWhite = !requiresAttributeCoverage && 0xffffffff == drawState.getCoverage(); if (skipCoverage) { desc->fCoverageInput = ProgramDesc::kTransBlack_ColorInput; @@ -694,8 +684,7 @@ void GrGpuGL::buildProgram(bool isPoints, int lastEnabledStage = -1; - if (!skipCoverage && (desc->fVertexLayout & - GrDrawTarget::kEdge_VertexLayoutBit)) { + if (!skipCoverage && (desc->fVertexLayout &GrDrawTarget::kEdge_VertexLayoutBit)) { desc->fVertexEdgeType = drawState.getVertexEdgeType(); } else { // use canonical value when not set to avoid cache misses @@ -709,52 +698,50 @@ void GrGpuGL::buildProgram(bool isPoints, stage.setEnabled(this->isStageEnabled(s)); bool skip = s < drawState.getFirstCoverageStage() ? skipColor : - skipCoverage; + skipCoverage; if (!skip && stage.isEnabled()) { lastEnabledStage = s; - const GrGLTexture* texture = - static_cast(drawState.getTexture(s)); - GrAssert(NULL != texture); const GrSamplerState& sampler = drawState.getSampler(s); - // we matrix to invert when orientation is TopDown, so make sure - // we aren't in that case before flagging as identity. - if (TextureMatrixIsIdentity(texture, sampler)) { - stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit; - } else if (!sampler.getMatrix().hasPerspective()) { - stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit; - } - + // FIXME: Still assuming one texture per custom stage + const GrCustomStage* customStage = drawState.getSampler(s).getCustomStage(); + const GrGLTexture* texture = static_cast(customStage->texture(0)); stage.fInConfigFlags = 0; - if (!this->glCaps().textureSwizzleSupport()) { - if (GrPixelConfigIsAlphaOnly(texture->config())) { - // if we don't have texture swizzle support then - // the shader must smear the single channel after - // reading the texture - if (this->glCaps().textureRedSupport()) { - // we can use R8 textures so use kSmearRed - stage.fInConfigFlags |= - StageDesc::kSmearRed_InConfigFlag; - } else { - // we can use A8 textures so use kSmearAlpha - stage.fInConfigFlags |= - StageDesc::kSmearAlpha_InConfigFlag; + if (NULL != texture) { + // We call this helper function rather then simply checking the client-specified + // texture matrix. This is because we may have to concat a y-inversion to account + // for texture orientation. + if (TextureMatrixIsIdentity(texture, sampler)) { + stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit; + } else if (!sampler.getMatrix().hasPerspective()) { + stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit; + } + if (!this->glCaps().textureSwizzleSupport()) { + if (GrPixelConfigIsAlphaOnly(texture->config())) { + // If we don't have texture swizzle support then the shader must smear the + // single channel after reading the texture. + if (this->glCaps().textureRedSupport()) { + // We can use R8 textures so use kSmearRed. + stage.fInConfigFlags |= StageDesc::kSmearRed_InConfigFlag; + } else { + // We can use A8 textures so use kSmearAlpha. + stage.fInConfigFlags |= StageDesc::kSmearAlpha_InConfigFlag; + } + } else if (sampler.swapsRAndB()) { + stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag; } - } else if (sampler.swapsRAndB()) { - stage.fInConfigFlags |= StageDesc::kSwapRAndB_InConfigFlag; } - } - if (GrPixelConfigIsUnpremultiplied(texture->config())) { - // The shader generator assumes that color channels are bytes - // when rounding. - GrAssert(4 == GrBytesPerPixel(texture->config())); - if (kUpOnWrite_DownOnRead_UnpremulConversion == - fUnpremulConversion) { - stage.fInConfigFlags |= - StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag; - } else { - stage.fInConfigFlags |= - StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag; + if (GrPixelConfigIsUnpremultiplied(texture->config())) { + // Assert that if we're doing a premul conversion that the texture is 1 byte + // per color component. The rounding performed by the shader generator (in + // normalized float color space) assumes this. + GrAssert(4 == GrBytesPerPixel(texture->config())); + if (kUpOnWrite_DownOnRead_UnpremulConversion == + fUnpremulConversion) { + stage.fInConfigFlags |= StageDesc::kMulRGBByAlpha_RoundDown_InConfigFlag; + } else { + stage.fInConfigFlags |= StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag; + } } } @@ -773,11 +760,9 @@ void GrGpuGL::buildProgram(bool isPoints, // when rounding. GrAssert(4 == GrBytesPerPixel(drawState.getRenderTarget()->config())); if (kUpOnWrite_DownOnRead_UnpremulConversion == fUnpremulConversion) { - desc->fOutputConfig = - ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig; + desc->fOutputConfig = ProgramDesc::kUnpremultiplied_RoundUp_OutputConfig; } else { - desc->fOutputConfig = - ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig; + desc->fOutputConfig = ProgramDesc::kUnpremultiplied_RoundDown_OutputConfig; } } else { desc->fOutputConfig = ProgramDesc::kPremultiplied_OutputConfig; @@ -785,18 +770,15 @@ void GrGpuGL::buildProgram(bool isPoints, desc->fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput; - // currently the experimental GS will only work with triangle prims - // (and it doesn't do anything other than pass through values from - // the VS to the FS anyway). + // Currently the experimental GS will only work with triangle prims (and it doesn't do anything + // other than pass through values fromthe VS to the FS anyway). #if 0 && GR_GL_EXPERIMENTAL_GS desc->fExperimentalGS = this->getCaps().fGeometryShaderSupport; #endif - // we want to avoid generating programs with different "first cov stage" - // values when they would compute the same result. - // We set field in the desc to kNumStages when either there are no - // coverage stages or the distinction between coverage and color is - // immaterial. + // We want to avoid generating programs with different "first cov stage" values when they would + // compute the same result. We set field in the desc to kNumStages when either there are no + // coverage stages or the distinction between coverage and color is immaterial. int firstCoverageStage = GrDrawState::kNumStages; desc->fFirstCoverageStage = GrDrawState::kNumStages; bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage; @@ -806,9 +788,8 @@ void GrGpuGL::buildProgram(bool isPoints, // other coverage inputs if (!hasCoverage) { - hasCoverage = - requiresAttributeCoverage || - (desc->fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit); + hasCoverage = requiresAttributeCoverage || + (desc->fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit); } if (hasCoverage) { @@ -818,20 +799,17 @@ void GrGpuGL::buildProgram(bool isPoints, } if (this->getCaps().fDualSourceBlendingSupport && - !(blendOpts & (kEmitCoverage_BlendOptFlag | - kCoverageAsAlpha_BlendOptFlag))) { + !(blendOpts & (kEmitCoverage_BlendOptFlag | kCoverageAsAlpha_BlendOptFlag))) { if (kZero_GrBlendCoeff == dstCoeff) { // write the coverage value to second color desc->fDualSrcOutput = ProgramDesc::kCoverage_DualSrcOutput; desc->fFirstCoverageStage = firstCoverageStage; } else if (kSA_GrBlendCoeff == dstCoeff) { - // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially - // cover + // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. desc->fDualSrcOutput = ProgramDesc::kCoverageISA_DualSrcOutput; desc->fFirstCoverageStage = firstCoverageStage; } else if (kSC_GrBlendCoeff == dstCoeff) { - // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially - // cover + // SA dst coeff becomes 1-(1-SA)*coverage when dst is partially covered. desc->fDualSrcOutput = ProgramDesc::kCoverageISC_DualSrcOutput; desc->fFirstCoverageStage = firstCoverageStage; } diff --git a/src/gpu/gl/GrGpuGL_unittest.cpp b/src/gpu/gl/GrGpuGL_unittest.cpp index fca908a..53fffca 100644 --- a/src/gpu/gl/GrGpuGL_unittest.cpp +++ b/src/gpu/gl/GrGpuGL_unittest.cpp @@ -37,8 +37,7 @@ typedef GrGLProgram::StageDesc StageDesc; // TODO: Effects should be able to register themselves for inclusion in the // randomly generated shaders. They should be able to configure themselves // randomly. -GrCustomStage* create_random_effect(StageDesc* stageDesc, - GrRandom* random) { +const GrCustomStage* create_random_effect(StageDesc* stageDesc, GrRandom* random) { enum EffectType { kConvolution_EffectType, kErode_EffectType, @@ -293,7 +292,7 @@ bool GrGpuGL::programUnitTest() { pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput; } - SkAutoTUnref customStages[GrDrawState::kNumStages]; + SkAutoTUnref customStages[GrDrawState::kNumStages]; for (int s = 0; s < GrDrawState::kNumStages; ++s) { StageDesc& stage = pdesc.fStages[s]; @@ -327,8 +326,10 @@ bool GrGpuGL::programUnitTest() { } GR_STATIC_ASSERT(sizeof(customStages) == GrDrawState::kNumStages * sizeof(GrCustomStage*)); - GrCustomStage** stages = reinterpret_cast(&customStages); - SkAutoTUnref program(GrGLProgram::Create(this->glContextInfo(), pdesc, stages)); + const GrCustomStage** stages = reinterpret_cast(&customStages); + SkAutoTUnref program(GrGLProgram::Create(this->glContextInfo(), + pdesc, + stages)); if (NULL == program.get()) { return false; } -- 2.7.4