aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu/src/GrGpuGLFixed.cpp
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-22 21:39:39 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-22 21:39:39 +0000
commitac10a2d039c5d52eed66e27cbbc503ab523c1cd5 (patch)
treec5be0c3dd15052016e7d32f376507cb1ea7101dd /gpu/src/GrGpuGLFixed.cpp
parentea8509cd3b1771b36054313d3ccd56679df56044 (diff)
add gpu backend (not hooked up yet)
git-svn-id: http://skia.googlecode.com/svn/trunk@649 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/src/GrGpuGLFixed.cpp')
-rw-r--r--gpu/src/GrGpuGLFixed.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/gpu/src/GrGpuGLFixed.cpp b/gpu/src/GrGpuGLFixed.cpp
new file mode 100644
index 0000000000..77bec40979
--- /dev/null
+++ b/gpu/src/GrGpuGLFixed.cpp
@@ -0,0 +1,342 @@
+/*
+ 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 {
+ GrScalar 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] = m[GrMatrix::kScaleX];
+ fMat[4] = m[GrMatrix::kSkewX];
+ fMat[12] = m[GrMatrix::kTransX];
+
+ fMat[1] = m[GrMatrix::kSkewY];
+ fMat[5] = m[GrMatrix::kScaleY];
+ fMat[13] = m[GrMatrix::kTransY];
+
+ fMat[3] = m[GrMatrix::kPersp0];
+ fMat[7] = m[GrMatrix::kPersp1];
+ fMat[15] = m[GrMatrix::kPersp2];
+
+ fMat[10] = GR_Scalar1; // z-scale
+ }
+};
+
+// these must match the order in the corresponding enum in GrGpu.h
+static const GLenum gMatrixMode2Enum[] = {
+ GL_MODELVIEW, GL_TEXTURE
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+GrGpuGLFixed::GrGpuGLFixed() {
+ resetContextHelper();
+}
+
+GrGpuGLFixed::~GrGpuGLFixed() {
+}
+
+void GrGpuGLFixed::resetContext() {
+ INHERITED::resetContext();
+ resetContextHelper();
+}
+
+void GrGpuGLFixed::resetContextHelper() {
+ GR_GL(Disable(GL_TEXTURE_2D));
+
+ 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));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR));
+ 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));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR));
+ GR_GL(TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA));
+
+ // this changes between GL_SRC_COLR and GL_SRC_ALPHA depending upon
+ // whether we have a (premultiplied) RGBA texture or just an ALPHA texture
+ //glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
+ fHWRGBOperand0 = (TextureEnvRGBOperands) -1;
+
+ GR_GL(ClientActiveTexture(GL_TEXTURE0));
+
+ fHWGeometryState.fVertexLayout = 0;
+ fHWGeometryState.fPositionPtr = (void*) ~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));
+
+ GrGLClearErr();
+ fTextVerts = false;
+
+ fHWTextureOrientation = (GrGLTexture::Orientation)-1; // illegal
+ 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(PrimitiveType type) {
+
+ bool usingTexture = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
+
+ if (usingTexture && fCurrDrawState.fSamplerState.isGradient()) {
+ unimpl("Fixed pipe doesn't support radial/sweep gradients");
+ return false;
+ }
+
+ flushGLStateCommon(type);
+
+ if (fRenderTargetChanged) {
+ flushProjectionMatrix();
+ fRenderTargetChanged = false;
+ }
+
+ bool wasUsingTexture = VertexHasTexCoords(fHWGeometryState.fVertexLayout);
+ if (usingTexture != wasUsingTexture) {
+ if (usingTexture) {
+ 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) {
+ GrAssert(fCurrDrawState.fSamplerState.getSampleMode() !=
+ GrSamplerState::kAlphaMod_SampleMode);
+ GR_GL(ShadeModel(GL_SMOOTH));
+ // invalidate the immediate mode color
+ fHWDrawState.fColor = GrColor_ILLEGAL;
+ } else {
+ GR_GL(ShadeModel(GL_FLAT));
+ }
+ }
+
+ if (kPoints_PrimitiveType == type &&
+ fHWDrawState.fPointSize != fCurrDrawState.fPointSize) {
+ GR_GL(PointSize(fCurrDrawState.fPointSize));
+ fHWDrawState.fPointSize = fCurrDrawState.fPointSize;
+ }
+
+ 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.
+ if (usingTexture) {
+ GrGLTexture* texture = (GrGLTexture*)fCurrDrawState.fTexture;
+ if (NULL != texture) {
+ TextureEnvRGBOperands nextRGBOperand0 =
+ (texture->uploadFormat() == GL_ALPHA) ?
+ kAlpha_TextureEnvRGBOperand :
+ kColor_TextureEnvRGBOperand;
+ if (fHWRGBOperand0 != nextRGBOperand0) {
+ GR_GL(TexEnvi(GL_TEXTURE_ENV,
+ GL_OPERAND0_RGB,
+ (nextRGBOperand0==kAlpha_TextureEnvRGBOperand) ?
+ GL_SRC_ALPHA :
+ GL_SRC_COLOR));
+ fHWRGBOperand0 = nextRGBOperand0;
+ }
+
+ if (fHWTextureOrientation != texture->orientation() ||
+ fHWDrawState.fMatrixModeCache[kTexture_MatrixMode] !=
+ fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]) {
+ GrGpuMatrix glm;
+ if (GrGLTexture::kBottomUp_Orientation == texture->orientation()) {
+ GrMatrix m(
+ GR_Scalar1, 0, 0,
+ 0, -GR_Scalar1, GR_Scalar1,
+ 0, 0, GrMatrix::I()[8]
+ );
+ m.preConcat(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+ glm.set(m);
+ } else {
+ glm.set(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
+ }
+ GR_GL(MatrixMode(gMatrixMode2Enum[kTexture_MatrixMode]));
+ GR_GL(LoadMatrixf(glm.fMat));
+ fHWDrawState.fMatrixModeCache[kTexture_MatrixMode] =
+ fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
+ fHWTextureOrientation = texture->orientation();
+ }
+ } else {
+ GrAssert(!"Rendering with texture vert flag set but no bound texture");
+ return false;
+ }
+ }
+
+ if (fHWDrawState.fMatrixModeCache[kModelView_MatrixMode] !=
+ fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
+ GrGpuMatrix glm;
+ glm.set(fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
+ GR_GL(MatrixMode(gMatrixMode2Enum[kModelView_MatrixMode]));
+ GR_GL(LoadMatrixf(glm.fMat));
+ fHWDrawState.fMatrixModeCache[kModelView_MatrixMode] =
+ fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
+ }
+ return true;
+}
+
+void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount) {
+
+ int newColorOffset, newTexCoordOffset;
+
+ GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
+ &newTexCoordOffset,
+ &newColorOffset);
+ int oldColorOffset, oldTexCoordOffset;
+ GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
+ &oldTexCoordOffset,
+ &oldColorOffset);
+
+ const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
+
+ if (kBuffer_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+ GrAssert(NULL != fGeometrySrc.fVertexBuffer);
+ GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
+ if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
+ GrGLVertexBuffer* buf =
+ (GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
+ GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
+ fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
+ }
+ } else {
+ if (kArray_GeometrySrcType == fGeometrySrc.fVertexSrc) {
+ posPtr = (void*)((intptr_t)fGeometrySrc.fVertexArray +
+ (intptr_t)posPtr);
+ } else {
+ GrAssert(kReserved_GeometrySrcType == fGeometrySrc.fVertexSrc);
+ posPtr = (void*)((intptr_t)fVertices.get() + (intptr_t)posPtr);
+ }
+ if (NULL != fHWGeometryState.fVertexBuffer) {
+ GR_GL(BindBuffer(GL_ARRAY_BUFFER, 0));
+ fHWGeometryState.fVertexBuffer = NULL;
+ }
+ }
+
+ if (kBuffer_GeometrySrcType == fGeometrySrc.fIndexSrc) {
+ GrAssert(NULL != fGeometrySrc.fIndexBuffer);
+ GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
+ if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
+ GrGLIndexBuffer* buf =
+ (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
+ GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
+ fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
+ }
+ } else if (NULL != fHWGeometryState.fIndexBuffer) {
+ GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
+ fHWGeometryState.fIndexBuffer = NULL;
+ }
+
+ GLenum scalarType;
+ if (fGeometrySrc.fVertexLayout & kTextFormat_VertexLayoutBit) {
+ scalarType = GrGLTextType;
+ } else {
+ scalarType = GrGLType;
+ }
+
+ bool baseChange = posPtr != fHWGeometryState.fPositionPtr;
+ bool scalarChange =
+ (GrGLTextType != GrGLType) &&
+ (kTextFormat_VertexLayoutBit &
+ (fHWGeometryState.fVertexLayout ^ fGeometrySrc.fVertexLayout));
+ bool strideChange = newStride != oldStride;
+ bool posChange = baseChange || scalarChange || strideChange;
+
+ if (posChange) {
+ GR_GL(VertexPointer(2, scalarType, newStride, posPtr));
+ fHWGeometryState.fPositionPtr = posPtr;
+ }
+
+ // need to enable array if tex coord offset is 0 (using positions as coords)
+ if (newTexCoordOffset >= 0) {
+ GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffset;
+ if (oldTexCoordOffset < 0) {
+ GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
+ }
+ if (posChange || newTexCoordOffset != oldTexCoordOffset) {
+ GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
+ }
+ } else if (oldTexCoordOffset >= 0) {
+ GR_GL(DisableClientState(GL_TEXTURE_COORD_ARRAY));
+ }
+
+ if (newColorOffset > 0) {
+ GLvoid* colorPtr = (int8_t*)posPtr + newColorOffset;
+ if (oldColorOffset <= 0) {
+ GR_GL(EnableClientState(GL_COLOR_ARRAY));
+ }
+ if (posChange || newColorOffset != oldColorOffset) {
+ GR_GL(ColorPointer(4, GL_UNSIGNED_BYTE, newStride, colorPtr));
+ }
+ } else if (oldColorOffset > 0) {
+ GR_GL(DisableClientState(GL_COLOR_ARRAY));
+ }
+
+ fHWGeometryState.fVertexLayout = fGeometrySrc.fVertexLayout;
+}
+
+#endif
+