diff options
author | 2010-12-22 21:39:39 +0000 | |
---|---|---|
committer | 2010-12-22 21:39:39 +0000 | |
commit | ac10a2d039c5d52eed66e27cbbc503ab523c1cd5 (patch) | |
tree | c5be0c3dd15052016e7d32f376507cb1ea7101dd /gpu/src/GrGpuGLFixed.cpp | |
parent | ea8509cd3b1771b36054313d3ccd56679df56044 (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.cpp | 342 |
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 + |