void GrGpuGLShaders::flushViewMatrix() { GrAssert(NULL != fCurrDrawState.fRenderTarget); GrMatrix m ( GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1, 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1, 0, 0, GrMatrix::I()[8]); m.setConcat(m, fCurrDrawState.fViewMatrix); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrScalar mt[] = { m[GrMatrix::kScaleX], m[GrMatrix::kSkewY], m[GrMatrix::kPersp0], m[GrMatrix::kSkewX], m[GrMatrix::kScaleY], m[GrMatrix::kPersp1], m[GrMatrix::kTransX], m[GrMatrix::kTransY], m[GrMatrix::kPersp2] }; #if ATTRIBUTE_MATRIX GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+0, mt+0)); GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+1, mt+3)); GR_GL(VertexAttrib4fv(VIEWMAT_ATTR_LOCATION+2, mt+6)); #else GR_GL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,1,false,mt)); #endif }
void GrGpuGLShaders::flushTextureMatrix(int stage) { GrAssert(NULL != fCurrDrawState.fTextures[stage]); GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[stage]; GrMatrix m = getSamplerMatrix(stage); GrSamplerState::SampleMode mode = fCurrDrawState.fSamplerStates[0].getSampleMode(); AdjustTextureMatrix(texture, mode, &m); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrScalar mt[] = { m[GrMatrix::kScaleX], m[GrMatrix::kSkewY], m[GrMatrix::kPersp0], m[GrMatrix::kSkewX], m[GrMatrix::kScaleY], m[GrMatrix::kPersp1], m[GrMatrix::kTransX], m[GrMatrix::kTransY], m[GrMatrix::kPersp2] }; #if ATTRIBUTE_MATRIX GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+0, mt+0)); GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3)); GR_GL(VertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6)); #else GR_GL(UniformMatrix3fv(fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni, 1, false, mt)); #endif }
void GrGLProgram::setColor(const GrDrawState& drawState, GrColor color, SharedGLState* sharedState) { const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); if (!drawState.hasColorVertexAttribute() || drawState.canIgnoreColorAttribute()) { switch (header.fColorInput) { case GrGLProgramDesc::kAttribute_ColorInput: SkASSERT(-1 != header.fColorAttributeIndex); if (sharedState->fConstAttribColor != color || sharedState->fConstAttribColorIndex != header.fColorAttributeIndex) { // OpenGL ES only supports the float varieties of glVertexAttrib GrGLfloat c[4]; GrColorToRGBAFloat(color, c); GL_CALL(VertexAttrib4fv(header.fColorAttributeIndex, c)); sharedState->fConstAttribColor = color; sharedState->fConstAttribColorIndex = header.fColorAttributeIndex; } break; case GrGLProgramDesc::kUniform_ColorInput: if (fColor != color && fBuilderOutput.fUniformHandles.fColorUni.isValid()) { // OpenGL ES doesn't support unsigned byte varieties of glUniform GrGLfloat c[4]; GrColorToRGBAFloat(color, c); fUniformManager->set4fv(fBuilderOutput.fUniformHandles.fColorUni, 1, c); fColor = color; } sharedState->fConstAttribColorIndex = -1; break; default: SkFAIL("Unexpected color type."); } } else { sharedState->fConstAttribColorIndex = -1; } }
void GrGpuGLShaders::flushTextureMatrix(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni; GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; if (NULL != texture) { if (GrGLProgram::kUnusedUniform != uni && (((1 << s) & fDirtyFlags.fTextureChangedMask) || getHWSamplerMatrix(s) != getSamplerMatrix(s))) { GrAssert(NULL != fCurrDrawState.fTextures[s]); GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; GrMatrix m = getSamplerMatrix(s); GrSamplerState::SampleMode mode = fCurrDrawState.fSamplerStates[s].getSampleMode(); AdjustTextureMatrix(texture, mode, &m); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrGLfloat mt[] = { GrScalarToFloat(m[GrMatrix::kMScaleX]), GrScalarToFloat(m[GrMatrix::kMSkewY]), GrScalarToFloat(m[GrMatrix::kMPersp0]), GrScalarToFloat(m[GrMatrix::kMSkewX]), GrScalarToFloat(m[GrMatrix::kMScaleY]), GrScalarToFloat(m[GrMatrix::kMPersp1]), GrScalarToFloat(m[GrMatrix::kMTransX]), GrScalarToFloat(m[GrMatrix::kMTransY]), GrScalarToFloat(m[GrMatrix::kMPersp2]) }; if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fStages[s].fTextureMatrixUni) { int baseIdx = GrGLProgram::TextureMatrixAttributeIdx(s); GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0)); GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3)); GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6)); } else { GL_CALL(UniformMatrix3fv(uni, 1, false, mt)); } recordHWSamplerMatrix(s, getSamplerMatrix(s)); } } }
void GrGpuGLShaders::flushViewMatrix() { const GrMatrix& vm = this->getDrawState().getViewMatrix(); if (GrGpuGLShaders::getHWViewMatrix() != vm) { const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); GrAssert(NULL != rt); GrMatrix m; m.setAll( GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1, 0,-GrIntToScalar(2) / rt->height(), GR_Scalar1, 0, 0, GrMatrix::I()[8]); m.setConcat(m, vm); // ES doesn't allow you to pass true to the transpose param, // so do our own transpose GrGLfloat mt[] = { GrScalarToFloat(m[GrMatrix::kMScaleX]), GrScalarToFloat(m[GrMatrix::kMSkewY]), GrScalarToFloat(m[GrMatrix::kMPersp0]), GrScalarToFloat(m[GrMatrix::kMSkewX]), GrScalarToFloat(m[GrMatrix::kMScaleY]), GrScalarToFloat(m[GrMatrix::kMPersp1]), GrScalarToFloat(m[GrMatrix::kMTransX]), GrScalarToFloat(m[GrMatrix::kMTransY]), GrScalarToFloat(m[GrMatrix::kMPersp2]) }; if (GrGLProgram::kSetAsAttribute == fProgramData->fUniLocations.fViewMatrixUni) { int baseIdx = GrGLProgram::ViewMatrixAttributeIdx(); GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0)); GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3)); GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6)); } else { GrAssert(GrGLProgram::kUnusedUniform != fProgramData->fUniLocations.fViewMatrixUni); GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni, 1, false, mt)); } this->recordHWViewMatrix(vm); } }
void GrGpuGLShaders::flushColor(GrColor color) { const ProgramDesc& desc = fCurrentProgram.getDesc(); const GrDrawState& drawState = this->getDrawState(); if (this->getVertexLayout() & kColor_VertexLayoutBit) { // color will be specified per-vertex as an attribute // invalidate the const vertex attrib color fHWDrawState.setColor(GrColor_ILLEGAL); } else { switch (desc.fColorInput) { case ProgramDesc::kAttribute_ColorInput: if (fHWDrawState.getColor() != color) { // OpenGL ES only supports the float varieties of // glVertexAttrib float c[] = GR_COLOR_TO_VEC4(color); GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c)); fHWDrawState.setColor(color); } break; case ProgramDesc::kUniform_ColorInput: if (fProgramData->fColor != color) { // OpenGL ES doesn't support unsigned byte varieties of // glUniform float c[] = GR_COLOR_TO_VEC4(color); GrAssert(GrGLProgram::kUnusedUniform != fProgramData->fUniLocations.fColorUni); GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorUni, 1, c)); fProgramData->fColor = color; } break; case ProgramDesc::kSolidWhite_ColorInput: case ProgramDesc::kTransBlack_ColorInput: break; default: GrCrash("Unknown color type."); } } if (fProgramData->fUniLocations.fColorFilterUni != GrGLProgram::kUnusedUniform && fProgramData->fColorFilterColor != drawState.getColorFilterColor()) { float c[] = GR_COLOR_TO_VEC4(drawState.getColorFilterColor()); GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c)); fProgramData->fColorFilterColor = drawState.getColorFilterColor(); } }
void GrGpuGL::flushColor(GrColor color) { const ProgramDesc& desc = fCurrentProgram->getDesc(); const GrDrawState& drawState = this->getDrawState(); if (this->getVertexLayout() & GrDrawState::kColor_VertexLayoutBit) { // color will be specified per-vertex as an attribute // invalidate the const vertex attrib color fHWConstAttribColor = GrColor_ILLEGAL; } else { switch (desc.fColorInput) { case ProgramDesc::kAttribute_ColorInput: if (fHWConstAttribColor != color) { // OpenGL ES only supports the float varieties of glVertexAttrib GrGLfloat c[4]; GrColorToRGBAFloat(color, c); GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(), c)); fHWConstAttribColor = color; } break; case ProgramDesc::kUniform_ColorInput: if (fCurrentProgram->fColor != color) { // OpenGL ES doesn't support unsigned byte varieties of glUniform GrGLfloat c[4]; GrColorToRGBAFloat(color, c); GrAssert(kInvalidUniformHandle != fCurrentProgram->fUniformHandles.fColorUni); fCurrentProgram->fUniformManager.set4fv( fCurrentProgram->fUniformHandles.fColorUni, 0, 1, c); fCurrentProgram->fColor = color; } break; case ProgramDesc::kSolidWhite_ColorInput: case ProgramDesc::kTransBlack_ColorInput: break; default: GrCrash("Unknown color type."); } } UniformHandle filterColorUni = fCurrentProgram->fUniformHandles.fColorFilterUni; if (kInvalidUniformHandle != filterColorUni && fCurrentProgram->fColorFilterColor != drawState.getColorFilterColor()) { GrGLfloat c[4]; GrColorToRGBAFloat(drawState.getColorFilterColor(), c); fCurrentProgram->fUniformManager.set4fv(filterColorUni, 0, 1, c); fCurrentProgram->fColorFilterColor = drawState.getColorFilterColor(); } }
void GrGLProgram::setCoverage(const GrDrawState& drawState, GrColor coverage, SharedGLState* sharedState) { const GrGLProgramDesc::KeyHeader& header = fDesc.getHeader(); if (!drawState.hasCoverageVertexAttribute()) { switch (header.fCoverageInput) { case GrGLProgramDesc::kAttribute_ColorInput: if (sharedState->fConstAttribCoverage != coverage || sharedState->fConstAttribCoverageIndex != header.fCoverageAttributeIndex) { // OpenGL ES only supports the float varieties of glVertexAttrib GrGLfloat c[4]; GrColorToRGBAFloat(coverage, c); GL_CALL(VertexAttrib4fv(header.fCoverageAttributeIndex, c)); sharedState->fConstAttribCoverage = coverage; sharedState->fConstAttribCoverageIndex = header.fCoverageAttributeIndex; } break; case GrGLProgramDesc::kUniform_ColorInput: if (fCoverage != coverage) { // OpenGL ES doesn't support unsigned byte varieties of glUniform GrGLfloat c[4]; GrColorToRGBAFloat(coverage, c); fUniformManager.set4fv(fUniformHandles.fCoverageUni, 1, c); fCoverage = coverage; } sharedState->fConstAttribCoverageIndex = -1; break; case GrGLProgramDesc::kSolidWhite_ColorInput: case GrGLProgramDesc::kTransBlack_ColorInput: sharedState->fConstAttribCoverageIndex = -1; break; default: GrCrash("Unknown coverage type."); } } else { sharedState->fConstAttribCoverageIndex = -1; } }
bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { if (!flushGLStateCommon(type)) { return false; } if (fDirtyFlags.fRenderTargetChanged) { // our coords are in pixel space and the GL matrices map to NDC // so if the viewport changed, our matrix is now wrong. #if ATTRIBUTE_MATRIX fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix(); #else // we assume all shader matrices may be wrong after viewport changes fProgramCache->invalidateViewMatrices(); #endif } if (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit) { // invalidate the immediate mode color fHWDrawState.fColor = GrColor_ILLEGAL; } else { if (fHWDrawState.fColor != fCurrDrawState.fColor) { // OpenGL ES only supports the float varities of glVertexAttrib float c[] = { GrColorUnpackR(fCurrDrawState.fColor) / 255.f, GrColorUnpackG(fCurrDrawState.fColor) / 255.f, GrColorUnpackB(fCurrDrawState.fColor) / 255.f, GrColorUnpackA(fCurrDrawState.fColor) / 255.f }; GR_GL(VertexAttrib4fv(COL_ATTR_LOCATION, c)); fHWDrawState.fColor = fCurrDrawState.fColor; } } buildProgram(type); fProgramData = fProgramCache->getProgramData(fCurrentProgram, this); if (fHWProgramID != fProgramData->fProgramID) { GR_GL(UseProgram(fProgramData->fProgramID)); fHWProgramID = fProgramData->fProgramID; } if (!fCurrentProgram.doGLSetup(type, fProgramData)) { return false; } #if ATTRIBUTE_MATRIX GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix; #else GrMatrix& currViewMatrix = fProgramData->fViewMatrix; #endif if (currViewMatrix != fCurrDrawState.fViewMatrix) { flushViewMatrix(); currViewMatrix = fCurrDrawState.fViewMatrix; } for (int s = 0; s < kNumStages; ++s) { GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s]; if (NULL != texture) { if (-1 != fProgramData->fUniLocations.fStages[s].fTextureMatrixUni && (((1 << s) & fDirtyFlags.fTextureChangedMask) || getHWSamplerMatrix(s) != getSamplerMatrix(s))) { flushTextureMatrix(s); recordHWSamplerMatrix(s, getSamplerMatrix(s)); } } const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s]; if (-1 != fProgramData->fUniLocations.fStages[s].fRadial2Uni && (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() || fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() || fProgramData->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) { flushRadial2(s); fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1(); fProgramData->fRadial2Radius0[s] = sampler.getRadial2Radius0(); fProgramData->fRadial2PosRoot[s] = sampler.isRadial2PosRoot(); } } resetDirtyFlags(); return true; }