diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-02-13 16:03:51 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-02-13 16:03:51 +0000 |
commit | 6a51dcbf81cff6d92996ab3f4c7457478e441896 (patch) | |
tree | 34448546ebbe9095235e96a53cfa604a724fdcd6 /src/gpu | |
parent | 1eeef1646d230cd352778a2b0f67725a60028595 (diff) |
Attempt to reland r7713 with fix.
git-svn-id: http://skia.googlecode.com/svn/trunk@7719 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 59 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.h | 37 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 4 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 31 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 121 |
5 files changed, 132 insertions, 120 deletions
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 75f9ea6ad5..a5014a6a9d 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -211,12 +211,8 @@ GrGLProgram::GrGLProgram(const GrGLContextInfo& gl, fFShaderID = 0; fProgramID = 0; - fViewMatrix = SkMatrix::InvalidMatrix(); - fViewportSize.set(-1, -1); - fOrigin = (GrSurfaceOrigin) -1; fColor = GrColor_ILLEGAL; fColorFilterColor = GrColor_ILLEGAL; - fRTHeight = -1; for (int s = 0; s < GrDrawState::kNumStages; ++s) { fEffects[s] = NULL; @@ -1051,15 +1047,9 @@ void GrGLProgram::setData(GrGpuGL* gpu, SharedGLState* sharedState) { const GrDrawState& drawState = gpu->getDrawState(); - int rtHeight = drawState.getRenderTarget()->height(); - if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni && - fRTHeight != rtHeight) { - fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(rtHeight)); - fRTHeight = rtHeight; - } - this->setColor(drawState, color, sharedState); this->setCoverage(drawState, coverage, sharedState); + this->setMatrixAndRenderTargetHeight(drawState); // Setup the SkXfermode::Mode-based colorfilter uniform if necessary if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fColorFilterUni && @@ -1157,3 +1147,50 @@ void GrGLProgram::setCoverage(const GrDrawState& drawState, } } } + +void GrGLProgram::setMatrixAndRenderTargetHeight(const GrDrawState& drawState) { + const GrRenderTarget* rt = drawState.getRenderTarget(); + SkISize size; + size.set(rt->width(), rt->height()); + + // Load the RT height uniform if it is needed to y-flip gl_FragCoord. + if (GrGLUniformManager::kInvalidUniformHandle != fUniformHandles.fRTHeightUni && + fMatrixState.fRenderTargetSize.fHeight != size.fHeight) { + fUniformManager.set1f(fUniformHandles.fRTHeightUni, SkIntToScalar(size.fHeight)); + } + + if (fMatrixState.fRenderTargetOrigin != rt->origin() || + !fMatrixState.fViewMatrix.cheapEqualTo(drawState.getViewMatrix()) || + fMatrixState.fRenderTargetSize != size) { + SkMatrix m; + if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { + m.setAll( + SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1, + 0,-SkIntToScalar(2) / size.fHeight, SK_Scalar1, + 0, 0, SkMatrix::I()[8]); + } else { + m.setAll( + SkIntToScalar(2) / size.fWidth, 0, -SK_Scalar1, + 0, SkIntToScalar(2) / size.fHeight,-SK_Scalar1, + 0, 0, SkMatrix::I()[8]); + } + m.setConcat(m, drawState.getViewMatrix()); + + // ES doesn't allow you to pass true to the transpose param so we do our own transpose. + GrGLfloat mt[] = { + SkScalarToFloat(m[SkMatrix::kMScaleX]), + SkScalarToFloat(m[SkMatrix::kMSkewY]), + SkScalarToFloat(m[SkMatrix::kMPersp0]), + SkScalarToFloat(m[SkMatrix::kMSkewX]), + SkScalarToFloat(m[SkMatrix::kMScaleY]), + SkScalarToFloat(m[SkMatrix::kMPersp1]), + SkScalarToFloat(m[SkMatrix::kMTransX]), + SkScalarToFloat(m[SkMatrix::kMTransY]), + SkScalarToFloat(m[SkMatrix::kMPersp2]) + }; + fUniformManager.setMatrix3f(fUniformHandles.fViewMatrixUni, mt); + fMatrixState.fViewMatrix = drawState.getViewMatrix(); + fMatrixState.fRenderTargetSize = size; + fMatrixState.fRenderTargetOrigin = rt->origin(); + } +} diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h index fd5e8e4b8e..5d02ba2a9c 100644 --- a/src/gpu/gl/GrGLProgram.h +++ b/src/gpu/gl/GrGLProgram.h @@ -74,6 +74,11 @@ public: const Desc& getDesc() { return fDesc; } /** + * Gets the GL program ID for this program. + */ + GrGLuint programID() const { return fProgramID; } + + /** * Attribute indices. These should not overlap. */ static int PositionAttributeIdx() { return 0; } @@ -99,6 +104,25 @@ public: }; /** + * The GrDrawState's view matrix along with the aspects of the render target determine the + * matrix sent to GL. The size of the render target affects the GL matrix because we must + * convert from Skia device coords to GL's normalized coords. Also the origin of the render + * target may require us to perform a mirror-flip. + */ + struct MatrixState { + SkMatrix fViewMatrix; + SkISize fRenderTargetSize; + GrSurfaceOrigin fRenderTargetOrigin; + + MatrixState() { this->invalidate(); } + void invalidate() { + fViewMatrix = SkMatrix::InvalidMatrix(); + fRenderTargetSize.fWidth = -1; // just make the first value compared illegal. + fRenderTargetOrigin = (GrSurfaceOrigin) -1; + } + }; + + /** * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a * draw occurs using the program after the program has already been bound. It also uses the * GrGpuGL object to bind the textures required by the GrGLEffects. @@ -174,6 +198,7 @@ public: friend class GrGLProgram; }; + private: GrGLProgram(const GrGLContextInfo& gl, const Desc& desc, @@ -220,6 +245,9 @@ private: // per-vertex coverages. void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*); + // Helper for setData() that sets the view matrix and loads the render target height uniform + void setMatrixAndRenderTargetHeight(const GrDrawState&); + typedef SkSTArray<4, UniformHandle, true> SamplerUniSArray; struct UniformHandles { @@ -247,17 +275,12 @@ private: GrGLuint fGShaderID; GrGLuint fFShaderID; GrGLuint fProgramID; - // The matrix sent to GL is determined by the client's matrix, - // the size of the viewport, and the origin of the render target. - SkMatrix fViewMatrix; - SkISize fViewportSize; - GrSurfaceOrigin fOrigin; // these reflect the current values of uniforms (GL uniform values travel with program) + MatrixState fMatrixState; GrColor fColor; GrColor fCoverage; GrColor fColorFilterColor; - int fRTHeight; GrGLEffect* fEffects[GrDrawState::kNumStages]; @@ -267,8 +290,6 @@ private: GrGLUniformManager fUniformManager; UniformHandles fUniformHandles; - friend class GrGpuGL; // TODO: remove this by adding getters and moving functionality. - typedef GrRefCnt INHERITED; }; diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index 56a29919fc..f14238cdd9 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -188,7 +188,7 @@ GrGpuGL::~GrGpuGL() { if (0 != fHWProgramID) { // detach the current program so there is no confusion on OpenGL's part // that we want it to be deleted - GrAssert(fHWProgramID == fCurrentProgram->fProgramID); + GrAssert(fHWProgramID == fCurrentProgram->programID()); GL_CALL(UseProgram(0)); } @@ -453,7 +453,7 @@ void GrGpuGL::onResetContext() { fHWBoundRenderTarget = NULL; - fHWPathMatrixState.invalidate(); + fHWPathStencilMatrixState.invalidate(); if (fCaps.pathStencilingSupport()) { // we don't use the model view matrix. GL_CALL(MatrixMode(GR_GL_MODELVIEW)); diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index b911f40b76..505c99c374 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -181,9 +181,8 @@ private: const GrGLContextInfo& fGL; }; - - // sets the MVP matrix uniform for currently bound program - void flushViewMatrix(DrawType type); + // sets the matrix for path stenciling (uses the GL fixed pipe matrices) + void flushPathStencilMatrix(); // flushes dithering, color-mask, and face culling stat void flushMiscFixedFunctionState(); @@ -305,25 +304,17 @@ private: } } fHWAAState; - struct { - SkMatrix fViewMatrix; - SkISize fRTSize; - GrSurfaceOrigin fLastOrigin; - void invalidate() { - fViewMatrix = SkMatrix::InvalidMatrix(); - fRTSize.fWidth = -1; // just make the first value compared illegal. - fLastOrigin = (GrSurfaceOrigin) -1; - } - } fHWPathMatrixState; - GrStencilSettings fHWStencilSettings; - TriState fHWStencilTestEnabled; + GrGLProgram::MatrixState fHWPathStencilMatrixState; + + GrStencilSettings fHWStencilSettings; + TriState fHWStencilTestEnabled; - GrDrawState::DrawFace fHWDrawFace; - TriState fHWWriteToColor; - TriState fHWDitherEnabled; - GrRenderTarget* fHWBoundRenderTarget; - GrTexture* fHWBoundTextures[GrDrawState::kNumStages]; + GrDrawState::DrawFace fHWDrawFace; + TriState fHWWriteToColor; + TriState fHWDitherEnabled; + GrRenderTarget* fHWBoundRenderTarget; + GrTexture* fHWBoundTextures[GrDrawState::kNumStages]; ///@} // we record what stencil format worked last time to hopefully exit early diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index feff02e94d..8ebe7a2d41 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -82,106 +82,68 @@ void GrGpuGL::abandonResources(){ #define GL_CALL(X) GR_GL_CALL(this->glInterface(), X) -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); - +void GrGpuGL::flushPathStencilMatrix() { + const SkMatrix& viewMatrix = this->getDrawState().getViewMatrix(); + const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); + SkISize size; + size.set(rt->width(), rt->height()); const SkMatrix& vm = this->getDrawState().getViewMatrix(); - if (kStencilPath_DrawType == type) { - if (fHWPathMatrixState.fLastOrigin != rt->origin() || - fHWPathMatrixState.fViewMatrix != vm || - fHWPathMatrixState.fRTSize != viewportSize) { - // rescale the coords from skia's "device" coords to GL's normalized coords, - // and perform a y-flip if required. - SkMatrix m; - if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { - m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height()); - m.postTranslate(-SK_Scalar1, SK_Scalar1); - } else { - m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height()); - m.postTranslate(-SK_Scalar1, -SK_Scalar1); - } - m.preConcat(vm); - - // GL wants a column-major 4x4. - GrGLfloat mv[] = { - // col 0 - SkScalarToFloat(m[SkMatrix::kMScaleX]), - SkScalarToFloat(m[SkMatrix::kMSkewY]), - 0, - SkScalarToFloat(m[SkMatrix::kMPersp0]), - - // col 1 - SkScalarToFloat(m[SkMatrix::kMSkewX]), - SkScalarToFloat(m[SkMatrix::kMScaleY]), - 0, - SkScalarToFloat(m[SkMatrix::kMPersp1]), - - // col 2 - 0, 0, 0, 0, - - // col3 - SkScalarToFloat(m[SkMatrix::kMTransX]), - SkScalarToFloat(m[SkMatrix::kMTransY]), - 0.0f, - SkScalarToFloat(m[SkMatrix::kMPersp2]) - }; - GL_CALL(MatrixMode(GR_GL_PROJECTION)); - GL_CALL(LoadMatrixf(mv)); - fHWPathMatrixState.fViewMatrix = vm; - fHWPathMatrixState.fRTSize = viewportSize; - fHWPathMatrixState.fLastOrigin = rt->origin(); - } - } else if (fCurrentProgram->fOrigin != rt->origin() || - !fCurrentProgram->fViewMatrix.cheapEqualTo(vm) || - fCurrentProgram->fViewportSize != viewportSize) { + if (fHWPathStencilMatrixState.fRenderTargetOrigin != rt->origin() || + fHWPathStencilMatrixState.fViewMatrix.cheapEqualTo(viewMatrix) || + fHWPathStencilMatrixState.fRenderTargetSize!= size) { + // rescale the coords from skia's "device" coords to GL's normalized coords, + // and perform a y-flip if required. SkMatrix m; if (kBottomLeft_GrSurfaceOrigin == rt->origin()) { - m.setAll( - SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1, - 0,-SkIntToScalar(2) / viewportSize.fHeight, SK_Scalar1, - 0, 0, SkMatrix::I()[8]); + m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height()); + m.postTranslate(-SK_Scalar1, SK_Scalar1); } else { - m.setAll( - SkIntToScalar(2) / viewportSize.fWidth, 0, -SK_Scalar1, - 0, SkIntToScalar(2) / viewportSize.fHeight,-SK_Scalar1, - 0, 0, SkMatrix::I()[8]); + m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height()); + m.postTranslate(-SK_Scalar1, -SK_Scalar1); } - m.setConcat(m, vm); + m.preConcat(vm); - // ES doesn't allow you to pass true to the transpose param, - // so do our own transpose - GrGLfloat mt[] = { + // GL wants a column-major 4x4. + GrGLfloat mv[] = { + // col 0 SkScalarToFloat(m[SkMatrix::kMScaleX]), SkScalarToFloat(m[SkMatrix::kMSkewY]), + 0, SkScalarToFloat(m[SkMatrix::kMPersp0]), + + // col 1 SkScalarToFloat(m[SkMatrix::kMSkewX]), SkScalarToFloat(m[SkMatrix::kMScaleY]), + 0, SkScalarToFloat(m[SkMatrix::kMPersp1]), + + // col 2 + 0, 0, 0, 0, + + // col3 SkScalarToFloat(m[SkMatrix::kMTransX]), SkScalarToFloat(m[SkMatrix::kMTransY]), + 0.0f, SkScalarToFloat(m[SkMatrix::kMPersp2]) }; - fCurrentProgram->fUniformManager.setMatrix3f( - fCurrentProgram->fUniformHandles.fViewMatrixUni, - mt); - fCurrentProgram->fViewMatrix = vm; - fCurrentProgram->fViewportSize = viewportSize; - fCurrentProgram->fOrigin = rt->origin(); + GL_CALL(MatrixMode(GR_GL_PROJECTION)); + GL_CALL(LoadMatrixf(mv)); + fHWPathStencilMatrixState.fViewMatrix = vm; + fHWPathStencilMatrixState.fRenderTargetSize = size; + fHWPathStencilMatrixState.fRenderTargetOrigin = rt->origin(); } } bool GrGpuGL::flushGraphicsState(DrawType type) { const GrDrawState& drawState = this->getDrawState(); - // GrGpu::setupClipAndFlushState should have already checked this - // and bailed if not true. + // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true. GrAssert(NULL != drawState.getRenderTarget()); - if (kStencilPath_DrawType != type) { + if (kStencilPath_DrawType == type) { + this->flushPathStencilMatrix(); + } else { this->flushMiscFixedFunctionState(); GrBlendCoeff srcCoeff; @@ -211,10 +173,12 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { } fCurrentProgram.get()->ref(); - if (fHWProgramID != fCurrentProgram->fProgramID) { - GL_CALL(UseProgram(fCurrentProgram->fProgramID)); - fHWProgramID = fCurrentProgram->fProgramID; + GrGLuint programID = fCurrentProgram->programID(); + if (fHWProgramID != programID) { + GL_CALL(UseProgram(programID)); + fHWProgramID = programID; } + fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff); this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff); @@ -233,7 +197,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type) { fCurrentProgram->setData(this, color, coverage, &fSharedGLProgramState); } this->flushStencil(type); - this->flushViewMatrix(type); this->flushScissor(); this->flushAAState(type); |