aboutsummaryrefslogtreecommitdiffstats
path: root/gpu/src/GrGpuGLFixed.cpp
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2011-03-14 11:20:24 -0400
committerDerek Sollenberger <djsollen@google.com>2011-03-14 16:33:36 -0400
commit05b6b4d746867a9fb02e14edfe1bf3685abeb813 (patch)
tree34b121f598d1693c014df48ee70bffa382b0cc23 /gpu/src/GrGpuGLFixed.cpp
parent6210a7c68844602ee390bcce61dbb637910a3c6b (diff)
downloadexternal_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.zip
external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.gz
external_skia-05b6b4d746867a9fb02e14edfe1bf3685abeb813.tar.bz2
Skia Merge (revision 922)
Change-Id: I7ed57d10905d8bad6486a4d7410165eec1cc2b4f
Diffstat (limited to 'gpu/src/GrGpuGLFixed.cpp')
-rw-r--r--gpu/src/GrGpuGLFixed.cpp327
1 files changed, 327 insertions, 0 deletions
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
new file mode 100644
index 0000000..695b22c
--- /dev/null
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -0,0 +1,327 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#include "GrGLConfig.h"
+
+#if GR_SUPPORT_GLES1 || GR_SUPPORT_GLDESKTOP
+
+#include "GrGpuGLFixed.h"
+#include "GrGpuVertex.h"
+
+#define SKIP_CACHE_CHECK true
+
+struct GrGpuMatrix {
+ GLfloat fMat[16];
+
+ void reset() {
+ Gr_bzero(fMat, sizeof(fMat));
+ fMat[0] = fMat[5] = fMat[10] = fMat[15] = GR_Scalar1;
+ }
+
+ 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
+ }
+};
+
+// these must match the order in the corresponding enum in GrGpu.h
+static const GLenum gMatrixMode2Enum[] = {
+ GL_MODELVIEW, GL_TEXTURE
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrGpuGLFixed::GrGpuGLFixed() {
+}
+
+GrGpuGLFixed::~GrGpuGLFixed() {
+}
+
+void GrGpuGLFixed::resetContext() {
+ INHERITED::resetContext();
+
+ GR_GL(Disable(GL_TEXTURE_2D));
+
+ for (int s = 0; s < kNumStages; ++s) {
+ setTextureUnit(s);
+ GR_GL(EnableClientState(GL_VERTEX_ARRAY));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0+s));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR));
+
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE0+s));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA));
+
+ // color oprand0 changes between GL_SRC_COLR and GL_SRC_ALPHA depending
+ // upon whether we have a (premultiplied) RGBA texture or just an ALPHA
+ // texture, e.g.:
+ //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ fHWRGBOperand0[s] = (TextureEnvRGBOperands) -1;
+ }
+
+ fHWGeometryState.fVertexLayout = 0;
+ fHWGeometryState.fVertexOffset = ~0;
+ GR_GL(EnableClientState(GL_VERTEX_ARRAY));
+ GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+ GR_GL(ShadeModel(GL_FLAT));
+ GR_GL(DisableClientState(GL_COLOR_ARRAY));
+
+ GR_GL(PointSize(1.f));
+
+ GrGLClearErr();
+ fTextVerts = false;
+
+ fBaseVertex = 0xffffffff;
+}
+
+
+void GrGpuGLFixed::flushProjectionMatrix() {
+ float mat[16];
+ Gr_bzero(mat, sizeof(mat));
+
+ GrAssert(NULL != fCurrDrawState.fRenderTarget);
+
+ mat[0] = 2.f / fCurrDrawState.fRenderTarget->width();
+ mat[5] = -2.f / fCurrDrawState.fRenderTarget->height();
+ mat[10] = -1.f;
+ mat[15] = 1;
+
+ mat[12] = -1.f;
+ mat[13] = 1.f;
+
+ GR_GL(MatrixMode(GL_PROJECTION));
+ GR_GL(LoadMatrixf(mat));
+}
+
+bool GrGpuGLFixed::flushGraphicsState(GrPrimitiveType type) {
+
+ bool usingTextures[kNumStages];
+
+ for (int s = 0; s < kNumStages; ++s) {
+ usingTextures[s] = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
+
+ if (usingTextures[s] && fCurrDrawState.fSamplerStates[s].isGradient()) {
+ unimpl("Fixed pipe doesn't support radial/sweep gradients");
+ return false;
+ }
+ }
+
+ if (!flushGLStateCommon(type)) {
+ return false;
+ }
+
+ if (fDirtyFlags.fRenderTargetChanged) {
+ flushProjectionMatrix();
+ }
+
+ for (int s = 0; s < kNumStages; ++s) {
+ bool wasUsingTexture = VertexUsesStage(s, fHWGeometryState.fVertexLayout);
+ if (usingTextures[s] != wasUsingTexture) {
+ setTextureUnit(s);
+ if (usingTextures[s]) {
+ GR_GL(Enable(GL_TEXTURE_2D));
+ } else {
+ GR_GL(Disable(GL_TEXTURE_2D));
+ }
+ }
+ }
+
+ uint32_t vertColor = (fGeometrySrc.fVertexLayout & kColor_VertexLayoutBit);
+ uint32_t prevVertColor = (fHWGeometryState.fVertexLayout &
+ kColor_VertexLayoutBit);
+
+ if (vertColor != prevVertColor) {
+ if (vertColor) {
+ GR_GL(ShadeModel(GL_SMOOTH));
+ // invalidate the immediate mode color
+ fHWDrawState.fColor = GrColor_ILLEGAL;
+ } else {
+ GR_GL(ShadeModel(GL_FLAT));
+ }
+ }
+
+
+ if (!vertColor && fHWDrawState.fColor != fCurrDrawState.fColor) {
+ GR_GL(Color4ub(GrColorUnpackR(fCurrDrawState.fColor),
+ GrColorUnpackG(fCurrDrawState.fColor),
+ GrColorUnpackB(fCurrDrawState.fColor),
+ GrColorUnpackA(fCurrDrawState.fColor)));
+ fHWDrawState.fColor = fCurrDrawState.fColor;
+ }
+
+ // set texture environment, decide whether we are modulating by RGB or A.
+ for (int s = 0; s < kNumStages; ++s) {
+ if (usingTextures[s]) {
+ GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTextures[s];
+ if (NULL != texture) {
+ TextureEnvRGBOperands nextRGBOperand0 =
+ (texture->config() == GrTexture::kAlpha_8_PixelConfig) ?
+ kAlpha_TextureEnvRGBOperand :
+ kColor_TextureEnvRGBOperand;
+ if (fHWRGBOperand0[s] != nextRGBOperand0) {
+ setTextureUnit(s);
+ GR_GL(TexEnvi(GL_TEXTURE_ENV,
+ GL_OPERAND0_RGB,
+ (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
+ GL_SRC_ALPHA :
+ GL_SRC_COLOR));
+ fHWRGBOperand0[s] = nextRGBOperand0;
+ }
+
+ if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
+ (fHWDrawState.fSamplerStates[s].getMatrix() !=
+ getSamplerMatrix(s))) {
+
+ GrMatrix texMat = getSamplerMatrix(s);
+ AdjustTextureMatrix(texture,
+ GrSamplerState::kNormal_SampleMode,
+ &texMat);
+ GrGpuMatrix glm;
+ glm.set(texMat);
+ setTextureUnit(s);
+ GR_GL(MatrixMode(GL_TEXTURE));
+ GR_GL(LoadMatrixf(glm.fMat));
+ recordHWSamplerMatrix(s, getSamplerMatrix(s));
+ }
+ } else {
+ GrAssert(!"Rendering with texture vert flag set but no bound texture");
+ return false;
+ }
+ }
+ }
+
+ if (fHWDrawState.fViewMatrix != fCurrDrawState.fViewMatrix) {
+ GrGpuMatrix glm;
+ glm.set(fCurrDrawState.fViewMatrix);
+ GR_GL(MatrixMode(GL_MODELVIEW));
+ GR_GL(LoadMatrixf(glm.fMat));
+ fHWDrawState.fViewMatrix =
+ fCurrDrawState.fViewMatrix;
+ }
+ resetDirtyFlags();
+ return true;
+}
+
+void GrGpuGLFixed::setupGeometry(int* startVertex,
+ int* startIndex,
+ int vertexCount,
+ int indexCount) {
+
+ int newColorOffset;
+ int newTexCoordOffsets[kNumStages];
+
+ GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
+ newTexCoordOffsets,
+ &newColorOffset);
+ int oldColorOffset;
+ int oldTexCoordOffsets[kNumStages];
+ GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
+ oldTexCoordOffsets,
+ &oldColorOffset);
+
+ bool indexed = NULL != startIndex;
+
+ int extraVertexOffset;
+ int extraIndexOffset;
+ setBuffers(indexed, &extraVertexOffset, &extraIndexOffset);
+
+ GLenum scalarType;
+ if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+ scalarType = GrGLTextType;
+ } else {
+ scalarType = GrGLType;
+ }
+
+ size_t vertexOffset = (*startVertex + extraVertexOffset) * newStride;
+ *startVertex = 0;
+ if (indexed) {
+ *startIndex += extraIndexOffset;
+ }
+
+ // all the Pointers must be set if any of these are true
+ bool allOffsetsChange = fHWGeometryState.fArrayPtrsDirty ||
+ vertexOffset != fHWGeometryState.fVertexOffset ||
+ newStride != oldStride;
+
+ // position and tex coord offsets change if above conditions are true
+ // or the type changed based on text vs nontext type coords.
+ bool posAndTexChange = allOffsetsChange ||
+ ((GrGLTextType != GrGLType) &&
+ (kTextFormat_VertexLayoutBit &
+ (fHWGeometryState.fVertexLayout ^
+ fGeometrySrc.fVertexLayout)));
+
+ if (posAndTexChange) {
+ GR_GL(VertexPointer(2, scalarType, newStride, (GLvoid*)vertexOffset));
+ fHWGeometryState.fVertexOffset = vertexOffset;
+ }
+
+ for (int s = 0; s < kNumStages; ++s) {
+ // need to enable array if tex coord offset is 0
+ // (using positions as coords)
+ if (newTexCoordOffsets[s] >= 0) {
+ GLvoid* texCoordOffset = (GLvoid*)(vertexOffset + newTexCoordOffsets[s]);
+ if (oldTexCoordOffsets[s] < 0) {
+ GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
+ GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
+ GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
+ } else if (posAndTexChange ||
+ newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
+ GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
+ GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordOffset));
+ }
+ } else if (oldTexCoordOffsets[s] >= 0) {
+ GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
+ GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+ }
+ }
+
+ if (newColorOffset > 0) {
+ GLvoid* colorOffset = (GLvoid*)(vertexOffset + newColorOffset);
+ if (oldColorOffset <= 0) {
+ GR_GL(EnableClientState(GL_COLOR_ARRAY));
+ GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
+ } else if (allOffsetsChange || newColorOffset != oldColorOffset) {
+ GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorOffset));
+ }
+ } else if (oldColorOffset > 0) {
+ GR_GL(DisableClientState(GL_COLOR_ARRAY));
+ }
+
+ fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+ fHWGeometryState.fArrayPtrsDirty = false;
+}
+
+#endif
+