void GrGpuGLShaders::flushRadial2(int s) { const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni; const GrSamplerState& sampler = this->getDrawState().getSampler(s); if (GrGLProgram::kUnusedUniform != uni && (fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() || fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() || fProgramData->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) { GrScalar centerX1 = sampler.getRadial2CenterX1(); GrScalar radius0 = sampler.getRadial2Radius0(); GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1; // when were in the degenerate (linear) case the second // value will be INF but the program doesn't read it. (We // use the same 6 uniforms even though we don't need them // all in the linear case just to keep the code complexity // down). float values[6] = { GrScalarToFloat(a), 1 / (2.f * GrScalarToFloat(a)), GrScalarToFloat(centerX1), GrScalarToFloat(radius0), GrScalarToFloat(GrMul(radius0, radius0)), sampler.isRadial2PosRoot() ? 1.f : -1.f }; GL_CALL(Uniform1fv(uni, 6, values)); fProgramData->fRadial2CenterX1[s] = sampler.getRadial2CenterX1(); fProgramData->fRadial2Radius0[s] = sampler.getRadial2Radius0(); fProgramData->fRadial2PosRoot[s] = sampler.isRadial2PosRoot(); } }
void GrGpuGLShaders::flushTextureDomain(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni; const GrDrawState& drawState = this->getDrawState(); if (GrGLProgram::kUnusedUniform != uni) { const GrRect &texDom = drawState.getSampler(s).getTextureDomain(); if (((1 << s) & fDirtyFlags.fTextureChangedMask) || fProgramData->fTextureDomain[s] != texDom) { fProgramData->fTextureDomain[s] = texDom; float values[4] = { GrScalarToFloat(texDom.left()), GrScalarToFloat(texDom.top()), GrScalarToFloat(texDom.right()), GrScalarToFloat(texDom.bottom()) }; const GrGLTexture* texture = static_cast<const GrGLTexture*>(drawState.getTexture(s)); GrGLTexture::Orientation orientation = texture->orientation(); // vertical flip if necessary if (GrGLTexture::kBottomUp_Orientation == orientation) { values[1] = 1.0f - values[1]; values[3] = 1.0f - values[3]; // The top and bottom were just flipped, so correct the ordering // of elements so that values = (l, t, r, b). SkTSwap(values[1], values[3]); } GL_CALL(Uniform4fv(uni, 1, values)); } } }
void GrGpuGLShaders::flushViewMatrix() { const GrMatrix& vm = this->getDrawState().getViewMatrix(); if (!fProgramData->fViewMatrix.cheapEqualTo(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]) }; GrAssert(GrGLProgram::kUnusedUniform != fProgramData->fUniLocations.fViewMatrixUni); GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni, 1, false, mt)); fProgramData->fViewMatrix = vm; } }
void set(const GrMatrix& m) { Gr_bzero(fMat, sizeof(fMat)); fMat[0] = GrScalarToFloat(m[GrMatrix::kScaleX]); fMat[4] = GrScalarToFloat(m[GrMatrix::kSkewX]); fMat[12] = GrScalarToFloat(m[GrMatrix::kTransX]); fMat[1] = GrScalarToFloat(m[GrMatrix::kSkewY]); fMat[5] = GrScalarToFloat(m[GrMatrix::kScaleY]); fMat[13] = GrScalarToFloat(m[GrMatrix::kTransY]); fMat[3] = GrScalarToFloat(m[GrMatrix::kPersp0]); fMat[7] = GrScalarToFloat(m[GrMatrix::kPersp1]); fMat[15] = GrScalarToFloat(m[GrMatrix::kPersp2]); fMat[10] = 1.f; // z-scale }
void GrGpuGL::flushTextureMatrix(int s) { const GrDrawState& drawState = this->getDrawState(); // FIXME: Still assuming only a single texture per effect const GrEffect* effect = drawState.getStage(s).getEffect(); if (0 == effect->numTextures()) { return; } const GrGLTexture* texture = static_cast<const GrGLTexture*>(effect->texture(0)); if (NULL != texture) { bool originChange = fCurrentProgram->fTextureOrigin[s] != texture->origin(); UniformHandle matrixUni = fCurrentProgram->fUniforms.fStages[s].fTextureMatrixUni; const GrMatrix& hwMatrix = fCurrentProgram->fTextureMatrices[s]; GrMatrix samplerMatrix; drawState.getStage(s).getTotalMatrix(&samplerMatrix); if (kInvalidUniformHandle != matrixUni && (originChange || !hwMatrix.cheapEqualTo(samplerMatrix))) { GrMatrix m = samplerMatrix; AdjustTextureMatrix(texture, &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]) }; fCurrentProgram->fUniformManager.setMatrix3f(matrixUni, mt); fCurrentProgram->fTextureMatrices[s] = samplerMatrix; } fCurrentProgram->fTextureOrigin[s] = texture->origin(); } }
void GrGpuGLShaders::flushRadial2(int stage) { const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[stage]; GrScalar centerX1 = sampler.getRadial2CenterX1(); GrScalar radius0 = sampler.getRadial2Radius0(); GrScalar a = GrMul(centerX1, centerX1) - GR_Scalar1; float unis[6] = { GrScalarToFloat(a), 1 / (2.f * unis[0]), GrScalarToFloat(centerX1), GrScalarToFloat(radius0), GrScalarToFloat(GrMul(radius0, radius0)), sampler.isRadial2PosRoot() ? 1.f : -1.f }; GR_GL(Uniform1fv(fProgramData->fUniLocations.fStages[stage].fRadial2Uni, 6, unis)); }
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::flushTextureMatrix(int s) { const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni; const GrDrawState& drawState = this->getDrawState(); const GrGLTexture* texture = static_cast<const GrGLTexture*>(drawState.getTexture(s)); if (NULL != texture) { const GrMatrix& hwMatrix = fProgramData->fTextureMatrices[s]; const GrMatrix& samplerMatrix = drawState.getSampler(s).getMatrix(); if (GrGLProgram::kUnusedUniform != uni && (((1 << s) & fDirtyFlags.fTextureChangedMask) || !hwMatrix.cheapEqualTo(samplerMatrix))) { GrMatrix m = samplerMatrix; GrSamplerState::SampleMode mode = drawState.getSampler(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]) }; GL_CALL(UniformMatrix3fv(uni, 1, false, mt)); fProgramData->fTextureMatrices[s] = samplerMatrix; } } }
void GrGpuGL::flushViewMatrix(DrawType type) { const GrGLRenderTarget* rt = static_cast<const GrGLRenderTarget*>(this->getDrawState().getRenderTarget()); SkISize viewportSize; const GrGLIRect& viewport = rt->getViewport(); viewportSize.set(viewport.fWidth, viewport.fHeight); const GrMatrix& vm = this->getDrawState().getViewMatrix(); if (kStencilPath_DrawType == type) { if (fHWPathMatrixState.fViewMatrix != vm || fHWPathMatrixState.fRTSize != viewportSize) { // rescale the coords from skia's "device" coords to GL's normalized coords, // and perform a y-flip. GrMatrix m; m.setScale(GrIntToScalar(2) / rt->width(), GrIntToScalar(-2) / rt->height()); m.postTranslate(-GR_Scalar1, GR_Scalar1); m.preConcat(vm); // GL wants a column-major 4x4. GrGLfloat mv[] = { // col 0 GrScalarToFloat(m[GrMatrix::kMScaleX]), GrScalarToFloat(m[GrMatrix::kMSkewY]), 0, GrScalarToFloat(m[GrMatrix::kMPersp0]), // col 1 GrScalarToFloat(m[GrMatrix::kMSkewX]), GrScalarToFloat(m[GrMatrix::kMScaleY]), 0, GrScalarToFloat(m[GrMatrix::kMPersp1]), // col 2 0, 0, 0, 0, // col3 GrScalarToFloat(m[GrMatrix::kMTransX]), GrScalarToFloat(m[GrMatrix::kMTransY]), 0.0f, GrScalarToFloat(m[GrMatrix::kMPersp2]) }; GL_CALL(MatrixMode(GR_GL_PROJECTION)); GL_CALL(LoadMatrixf(mv)); fHWPathMatrixState.fViewMatrix = vm; fHWPathMatrixState.fRTSize = viewportSize; } } else if (!fCurrentProgram->fViewMatrix.cheapEqualTo(vm) || fCurrentProgram->fViewportSize != viewportSize) { GrMatrix m; m.setAll( GrIntToScalar(2) / viewportSize.fWidth, 0, -GR_Scalar1, 0,-GrIntToScalar(2) / viewportSize.fHeight, 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]) }; fCurrentProgram->fUniformManager.setMatrix3f(fCurrentProgram->fUniforms.fViewMatrixUni, mt); fCurrentProgram->fViewMatrix = vm; fCurrentProgram->fViewportSize = viewportSize; } }