aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-13 13:53:29 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-02-13 13:53:29 +0000
commitd2afa6e45319849accb3ec4eefeb3e7afc96b93d (patch)
tree34448546ebbe9095235e96a53cfa604a724fdcd6 /src/gpu/gl
parent1780a3cc84b670f02d11858305598577cdea7730 (diff)
Move view matrix flush to GrGLPrograms.
Review URL: https://codereview.appspot.com/7322064 git-svn-id: http://skia.googlecode.com/svn/trunk@7713 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl')
-rw-r--r--src/gpu/gl/GrGLProgram.cpp59
-rw-r--r--src/gpu/gl/GrGLProgram.h37
-rw-r--r--src/gpu/gl/GrGpuGL.cpp4
-rw-r--r--src/gpu/gl/GrGpuGL.h31
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp121
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);