Towards issue #106
Adds notion of texture multiple stages but currently just uses 1. git-svn-id: http://skia.googlecode.com/svn/trunk@694 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a76de3d1a9
commit
8531c1cea2
@ -129,9 +129,9 @@ public:
|
||||
void setDefaultRenderTargetSize(uint32_t width, uint32_t height);
|
||||
GrRenderTarget* defaultRenderTarget() { return fGpu->defaultRenderTarget(); }
|
||||
|
||||
void setTexture(GrTexture* texture);
|
||||
void setSamplerState(const GrSamplerState&);
|
||||
void setTextureMatrix(const GrMatrix& m);
|
||||
void setTexture(int stage, GrTexture* texture);
|
||||
void setSamplerState(int stage, const GrSamplerState&);
|
||||
void setTextureMatrix(int stage, const GrMatrix& m);
|
||||
|
||||
void setAntiAlias(bool);
|
||||
void setDither(bool);
|
||||
|
@ -33,6 +33,27 @@ class GrIndexBuffer;
|
||||
|
||||
class GrDrawTarget : public GrRefCnt {
|
||||
public:
|
||||
/**
|
||||
* Number of texture stages. Each stage takes as input a color and
|
||||
* 2D texture coordinates. The color input to the first enabled stage is the
|
||||
* per-vertex color or the constant color (setColor/setAlpha) if there are no
|
||||
* per-vertex colors. For subsequent stages the input color is the output
|
||||
* color from the previous enabled stage. The output color of each stage is
|
||||
* the input color modulated with the result of a texture lookup. Texture
|
||||
* lookups are specified by a texture (setTexture), a texture matrix
|
||||
* (setTextureMatrix), and a sampler (setSamplerState). Texture coordinates
|
||||
* for each stage come from the vertices based on a GrVertexLayout bitfield.
|
||||
* The output fragment color is the output color of the last enabled stage.
|
||||
* The presence or absence of texture coordinates for each stage in the
|
||||
* vertex layout indicates whether a stage is enabled or not.
|
||||
*/
|
||||
|
||||
// Currently there is just one stage but this will be changed soon.
|
||||
enum {
|
||||
kNumStages = 1,
|
||||
kMaxTexCoords = kNumStages
|
||||
};
|
||||
|
||||
/**
|
||||
* Geometric primitives used for drawing.
|
||||
*/
|
||||
@ -124,25 +145,20 @@ public:
|
||||
};
|
||||
|
||||
protected:
|
||||
enum MatrixMode {
|
||||
kModelView_MatrixMode = 0,
|
||||
kTexture_MatrixMode,
|
||||
|
||||
kMatrixModeCount
|
||||
};
|
||||
|
||||
struct DrState {
|
||||
uint32_t fFlagBits;
|
||||
BlendCoeff fSrcBlend;
|
||||
BlendCoeff fDstBlend;
|
||||
GrTexture* fTexture;
|
||||
GrSamplerState fSamplerState;
|
||||
GrTexture* fTextures[kNumStages];
|
||||
GrSamplerState fSamplerStates[kNumStages];
|
||||
GrRenderTarget* fRenderTarget;
|
||||
GrColor fColor;
|
||||
float fPointSize;
|
||||
StencilPass fStencilPass;
|
||||
bool fReverseFill;
|
||||
GrMatrix fMatrixModeCache[kMatrixModeCount];
|
||||
GrMatrix fViewMatrix;
|
||||
GrMatrix fTextureMatrices[kNumStages];
|
||||
bool operator ==(const DrState& s) const {
|
||||
return 0 == memcmp(this, &s, sizeof(DrState));
|
||||
}
|
||||
@ -172,10 +188,12 @@ public:
|
||||
/**
|
||||
* Sets the texture used at the next drawing call
|
||||
*
|
||||
* @param stage The texture stage for which the texture will be set
|
||||
*
|
||||
* @param texture The texture to set. Can be NULL though there is no advantage
|
||||
* to settings a NULL texture if doing non-textured drawing
|
||||
*/
|
||||
void setTexture(GrTexture* texture);
|
||||
void setTexture(int stage, GrTexture* texture);
|
||||
|
||||
/**
|
||||
* Retrieves the currently set texture.
|
||||
@ -184,7 +202,7 @@ public:
|
||||
* texture has been set, NULL was most recently passed to
|
||||
* setTexture, or the last setTexture was destroyed.
|
||||
*/
|
||||
GrTexture* currentTexture() const;
|
||||
GrTexture* currentTexture(int stage) const;
|
||||
|
||||
/**
|
||||
* Sets the rendertarget used at the next drawing call
|
||||
@ -210,10 +228,10 @@ public:
|
||||
*
|
||||
* @param samplerState Specifies the sampler state.
|
||||
*/
|
||||
void setSamplerState(const GrSamplerState& samplerState);
|
||||
void setSamplerState(int stage, const GrSamplerState& samplerState);
|
||||
|
||||
/**
|
||||
* Sets the matrix applied to texture coordinates.
|
||||
* Sets the matrix applied to texture coordinates for a stage.
|
||||
*
|
||||
* The post-matrix texture coordinates in the square [0,1]^2 cover the
|
||||
* entire area of the texture. This means the full POT width when a NPOT
|
||||
@ -223,11 +241,10 @@ public:
|
||||
* coordinates. In the latter case the texture matrix is applied to the
|
||||
* pre-modelview position values.
|
||||
*
|
||||
* @param m the matrix used to transform the texture coordinates.
|
||||
* @param stage the stage for which to set a matrix.
|
||||
* @param m the matrix used to transform the texture coordinates.
|
||||
*/
|
||||
void setTextureMatrix(const GrMatrix& m) {
|
||||
this->loadMatrix(m, kTexture_MatrixMode);
|
||||
}
|
||||
void setTextureMatrix(int stage, const GrMatrix& m);
|
||||
|
||||
/**
|
||||
* Sets the matrix applied to veretx positions.
|
||||
@ -238,9 +255,7 @@ public:
|
||||
*
|
||||
* @param m the matrix used to transform the vertex positions.
|
||||
*/
|
||||
void setViewMatrix(const GrMatrix& m) {
|
||||
this->loadMatrix(m, kModelView_MatrixMode);
|
||||
}
|
||||
void setViewMatrix(const GrMatrix& m);
|
||||
|
||||
/**
|
||||
* Multiplies the current view matrix by a matrix
|
||||
@ -379,38 +394,77 @@ public:
|
||||
void copyDrawState(const GrDrawTarget& srcTarget);
|
||||
|
||||
/**
|
||||
* Flags that indicate the layout of vertex data.
|
||||
* The format of vertices is represented as a bitfield of flags.
|
||||
* Flags that indicate the layout of vertex data. Vertices always contain
|
||||
* positions and may also contain up to kMaxTexCoords sets of 2D texture
|
||||
* coordinates and per-vertex colors. Each stage can use any of the texture
|
||||
* coordinates as its input texture coordinates or it may use the positions.
|
||||
*
|
||||
* kSeparateTexCoord_VertexLayoutBit is incompatible with
|
||||
* kPositionAsTexCoord_VertexLayoutBit. kTextFormat_VertexLayoutBit is
|
||||
* incompatible with any other flags.
|
||||
* If no texture coordinates are specified for a stage then the stage is
|
||||
* disabled.
|
||||
*
|
||||
* When kTextFormat_VertexLayoutBit is set:
|
||||
* Texture coordinates are separate.
|
||||
* Positions and Texture coordinates are SkGpuTextVertex.
|
||||
* For non-text vertices:
|
||||
* Position and texture coordinates are GrPoints.
|
||||
* Colors are GrColors.
|
||||
* Only one type of texture coord can be specified per stage. For
|
||||
* example StageTexCoordVertexLayoutBit(0, 2) and
|
||||
* StagePosAsTexCoordVertexLayoutBit(0) cannot both be specified.
|
||||
*
|
||||
* The order is always positions, texture coords, colors.
|
||||
* The order in memory is always (position, texture coord 0, ..., color)
|
||||
* with any unused fields omitted. Note that this means that if only texture
|
||||
* coordinates 1 is referenced then there is no texture coordinates 0 and
|
||||
* the order would be (position, texture coordinate 1[, color]).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Generates a bit indicating that a texture stage uses texture coordinates
|
||||
*
|
||||
* @param stage the stage that will use texture coordinates.
|
||||
* @param texCoordIdx the index of the texture coordinates to use
|
||||
*
|
||||
* @return the bit to add to a GrVertexLayout bitfield.
|
||||
*/
|
||||
static int StageTexCoordVertexLayoutBit(int stage, int texCoordIdx) {
|
||||
GrAssert(stage < kNumStages);
|
||||
GrAssert(texCoordIdx < kMaxTexCoords);
|
||||
return 1 << (stage + (texCoordIdx * kNumStages));
|
||||
}
|
||||
private:
|
||||
static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
|
||||
public:
|
||||
/**
|
||||
* Generates a bit indicating that a texture stage uses the position
|
||||
* as its texture coordinate.
|
||||
*
|
||||
* @param stage the stage that will use position as texture
|
||||
* coordinates.
|
||||
*
|
||||
* @return the bit to add to a GrVertexLayout bitfield.
|
||||
*/
|
||||
static int StagePosAsTexCoordVertexLayoutBit(int stage) {
|
||||
GrAssert(stage < kNumStages);
|
||||
return (1 << (TEX_COORD_BIT_CNT + stage));
|
||||
}
|
||||
private:
|
||||
static const int STAGE_BIT_CNT = TEX_COORD_BIT_CNT + kNumStages;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Additional Bits that can be specified in GrVertexLayout.
|
||||
*/
|
||||
enum VertexLayoutBits {
|
||||
kSeparateTexCoord_VertexLayoutBit = 0x1, //<! vertices have texture
|
||||
// coords that are not
|
||||
// inferred from the
|
||||
// positions
|
||||
kPositionAsTexCoord_VertexLayoutBit = 0x2, //<! vertices use positions
|
||||
// as texture coords.
|
||||
kColor_VertexLayoutBit = 0x4, //<! vertices have colors
|
||||
kTextFormat_VertexLayoutBit = 0x8, //<! vertices represent glyphs
|
||||
// and therefore contain
|
||||
// two GrGpuTextVertexs.
|
||||
// One for pos and one for
|
||||
// text coords.
|
||||
|
||||
kColor_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 0),
|
||||
//<! vertices have colors
|
||||
kTextFormat_VertexLayoutBit = 1 << (STAGE_BIT_CNT + 1),
|
||||
//<! use text vertices. (Pos
|
||||
// and tex coords may be
|
||||
// a different type for
|
||||
// text [GrGpuTextVertex vs
|
||||
// GrPoint].)
|
||||
// for below assert
|
||||
kDummy,
|
||||
kHighVertexLayoutBit = kDummy - 1
|
||||
};
|
||||
// make sure we haven't exceeded the number of bits in GrVertexLayout.
|
||||
GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
|
||||
|
||||
/**
|
||||
@ -619,6 +673,7 @@ public:
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers for picking apart vertex layouts
|
||||
|
||||
/**
|
||||
* Helper function to compute the size of a vertex from a vertex layout
|
||||
@ -626,12 +681,27 @@ public:
|
||||
*/
|
||||
static size_t VertexSize(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function for determining the index of texture coordinates that
|
||||
* is input for a texture stage. Note that a stage may instead use positions
|
||||
* as texture coordinates, in which case the result of the function is
|
||||
* indistinguishable from the case when the stage is disabled.
|
||||
*
|
||||
* @param stage the stage to query
|
||||
* @param vertexLayout layout to query
|
||||
*
|
||||
* @return the texture coordinate index or -1 if the stage doesn't use
|
||||
* separate (non-position) texture coordinates.
|
||||
*/
|
||||
static int VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the offset of texture coordinates in a vertex
|
||||
* @return offset of texture coordinates in vertex layout or -1 if the
|
||||
* layout has no texture coordinates.
|
||||
* layout has no texture coordinates. Will be 0 if positions are
|
||||
* used as texture coordinates for the stage.
|
||||
*/
|
||||
static int VertexTexCoordOffset(GrVertexLayout vertexLayout);
|
||||
static int VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the offset of the color in a vertex
|
||||
@ -641,25 +711,62 @@ public:
|
||||
static int VertexColorOffset(GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute vertex size and component offsets.
|
||||
* @param texCoordOffset after return it is the offset of texture coords
|
||||
* in vertex layout or -1 if the layout has no
|
||||
* texture coords.
|
||||
* @param colorOffset after return it is the offset of color in vertex
|
||||
* layout or -1 if the layout has no color.
|
||||
* @return size of a single vertex.
|
||||
* Helper function to determine if vertex layout contains explicit texture
|
||||
* coordinates of some index.
|
||||
*
|
||||
* @param coordIndex the tex coord index to query
|
||||
* @param vertexLayout layout to query
|
||||
*
|
||||
* @return true if vertex specifies texture coordinates for the index,
|
||||
* false otherwise.
|
||||
*/
|
||||
static int VertexSizeAndOffsets(GrVertexLayout vertexLayout,
|
||||
int* texCoordOffset,
|
||||
int* colorOffset);
|
||||
static bool VertexUsesTexCoordIdx(int coordIndex,
|
||||
GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to determine if vertex layout contains either explicit or
|
||||
* implicit texture coordinates.
|
||||
* implicit texture coordinates for a stage.
|
||||
*
|
||||
* @return true if vertex specifies texture coordinates, false otherwise.
|
||||
* @param stage the stage to query
|
||||
* @param vertexLayout layout to query
|
||||
*
|
||||
* @return true if vertex specifies texture coordinates for the stage,
|
||||
* false otherwise.
|
||||
*/
|
||||
static bool VertexHasTexCoords(GrVertexLayout vertexLayout);
|
||||
static bool VertexUsesStage(int stage, GrVertexLayout vertexLayout);
|
||||
|
||||
/**
|
||||
* Helper function to compute the size of each vertex and the offsets of
|
||||
* texture coordinates and color. Determines tex coord offsets by tex coord
|
||||
* index rather than by stage. (Each stage can be mapped to any t.c. index
|
||||
* by StageTexCoordVertexLayoutBit.)
|
||||
*
|
||||
* @param vertexLayout the layout to query
|
||||
* @param texCoordOffsetsByIdx after return it is the offset of each
|
||||
* tex coord index in the vertex or -1 if
|
||||
* index isn't used.
|
||||
* @return size of a single vertex
|
||||
*/
|
||||
static int VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
|
||||
int texCoordOffsetsByIdx[kMaxTexCoords],
|
||||
int *colorOffset);
|
||||
|
||||
/**
|
||||
* Helper function to compute the size of each vertex and the offsets of
|
||||
* texture coordinates and color. Determines tex coord offsets by stage
|
||||
* rather than by index. (Each stage can be mapped to any t.c. index
|
||||
* by StageTexCoordVertexLayoutBit.) If a stage uses positions for
|
||||
* tex coords then that stage's offset will be 0 (positions are always at 0).
|
||||
*
|
||||
* @param vertexLayout the layout to query
|
||||
* @param texCoordOffsetsByStage after return it is the offset of each
|
||||
* tex coord index in the vertex or -1 if
|
||||
* index isn't used.
|
||||
* @return size of a single vertex
|
||||
*/
|
||||
static int VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
|
||||
int texCoordOffsetsByStage[kNumStages],
|
||||
int *colorOffset);
|
||||
protected:
|
||||
|
||||
// Helpers for GrDrawTarget subclasses that won't have private access to
|
||||
@ -708,9 +815,6 @@ protected:
|
||||
|
||||
DrState fCurrDrawState;
|
||||
|
||||
// set texture or modelview matrix
|
||||
void loadMatrix(const GrMatrix&, MatrixMode);
|
||||
|
||||
// not meant for outside usage. Could cause problems if calls between
|
||||
// the save and restore mess with reserved geometry state.
|
||||
class AutoGeometrySrcRestore {
|
||||
@ -731,6 +835,8 @@ protected:
|
||||
AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
|
||||
};
|
||||
|
||||
private:
|
||||
void VertexLayoutUnitTest();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -90,6 +90,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define GR_SUPPORT_GLES (GR_SUPPORT_GLES1 || GR_SUPPORT_GLES2)
|
||||
|
||||
#ifndef GR_SUPPORT_GLDESKTOP
|
||||
#if defined(GR_INCLUDE_GLDESKTOP)
|
||||
#define GR_SUPPORT_GLDESKTOP 1
|
||||
@ -155,20 +157,6 @@
|
||||
//
|
||||
// End including GL headers
|
||||
|
||||
#if GL_VERSION_1_1
|
||||
#define GR_GL_DESKTOP 1
|
||||
#define GR_GL_ES 0
|
||||
#else
|
||||
#ifndef GL_ES_VERSION_2_0
|
||||
GR_STATIC_ASSERT(GL_VERSION_ES_CM_1_0 ||
|
||||
GL_VERSION_ES_CL_1_0 ||
|
||||
GL_VERSION_ES_CM_1_1 ||
|
||||
GL_VERSION_ES_CL_1_1);
|
||||
#endif
|
||||
#define GR_GL_DESKTOP 0
|
||||
#define GR_GL_ES 1
|
||||
#endif
|
||||
|
||||
#if GR_SCALAR_IS_FIXED
|
||||
#define GrGLType GL_FIXED
|
||||
#elif GR_SCALAR_IS_FLOAT
|
||||
|
@ -24,7 +24,6 @@ class GrSamplerState {
|
||||
public:
|
||||
enum SampleMode {
|
||||
kNormal_SampleMode, //!< sample color directly
|
||||
kAlphaMod_SampleMode, //!< modulate with alpha only
|
||||
kRadial_SampleMode, //!< treat as radial gradient
|
||||
kRadial2_SampleMode, //!< treat as 2-point radial gradient
|
||||
kSweep_SampleMode, //!< treat as sweep gradient
|
||||
|
@ -138,9 +138,9 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
|
||||
if (NULL != texture) {
|
||||
GrGpu::AutoStateRestore asr(fGpu);
|
||||
fGpu->setRenderTarget(texture->asRenderTarget());
|
||||
fGpu->setTexture(clampEntry->texture());
|
||||
fGpu->setTexture(0, clampEntry->texture());
|
||||
fGpu->setStencilPass(GrGpu::kNone_StencilPass);
|
||||
fGpu->setTextureMatrix(GrMatrix::I());
|
||||
fGpu->setTextureMatrix(0, GrMatrix::I());
|
||||
fGpu->setViewMatrix(GrMatrix::I());
|
||||
fGpu->setAlpha(0xff);
|
||||
fGpu->setBlendFunc(GrGpu::kOne_BlendCoeff, GrGpu::kZero_BlendCoeff);
|
||||
@ -150,10 +150,10 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
|
||||
GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
|
||||
GrSamplerState::kClamp_WrapMode,
|
||||
sampler.isFilter());
|
||||
fGpu->setSamplerState(stretchSampler);
|
||||
fGpu->setSamplerState(0, stretchSampler);
|
||||
|
||||
static const GrVertexLayout layout =
|
||||
GrDrawTarget::kSeparateTexCoord_VertexLayoutBit;
|
||||
GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
|
||||
GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0);
|
||||
|
||||
if (arg.succeeded()) {
|
||||
@ -303,7 +303,7 @@ static void setStrokeRectStrip(GrPoint verts[10], const GrRect& rect,
|
||||
|
||||
void GrContext::drawRect(const GrRect& rect, bool useTexture, GrScalar width) {
|
||||
GrVertexLayout layout = useTexture ?
|
||||
GrDrawTarget::kPositionAsTexCoord_VertexLayoutBit :
|
||||
GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
|
||||
0;
|
||||
|
||||
static const int worstCaseVertCount = 10;
|
||||
@ -582,7 +582,7 @@ void GrContext::drawPath(GrPathIter* path, PathFills fill,
|
||||
tol);
|
||||
GrVertexLayout layout = 0;
|
||||
if (useTexture) {
|
||||
layout = GrDrawTarget::kPositionAsTexCoord_VertexLayoutBit;
|
||||
layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
|
||||
}
|
||||
// add 4 to hold the bounding rect
|
||||
GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, maxPts + 4, 0);
|
||||
@ -808,14 +808,14 @@ void GrContext::writePixels(int left, int top, int width, int height,
|
||||
fGpu->setViewMatrix(matrix);
|
||||
matrix.setScale(GR_Scalar1 / texture->allocWidth(),
|
||||
GR_Scalar1 / texture->allocHeight());
|
||||
fGpu->setTextureMatrix(matrix);
|
||||
fGpu->setTextureMatrix(0, matrix);
|
||||
|
||||
fGpu->disableState(GrDrawTarget::kClip_StateBit);
|
||||
fGpu->setAlpha(0xFF);
|
||||
fGpu->setBlendFunc(GrDrawTarget::kOne_BlendCoeff,
|
||||
GrDrawTarget::kZero_BlendCoeff);
|
||||
fGpu->setTexture(texture);
|
||||
fGpu->setSamplerState(GrSamplerState::ClampNoFilter());
|
||||
fGpu->setTexture(0, texture);
|
||||
fGpu->setSamplerState(0, GrSamplerState::ClampNoFilter());
|
||||
|
||||
this->fillRect(GrRect(0, 0, GrIntToScalar(width), GrIntToScalar(height)),
|
||||
true);
|
||||
@ -841,8 +841,8 @@ GrIndexBuffer* GrContext::createIndexBuffer(uint32_t size, bool dynamic) {
|
||||
return fGpu->createIndexBuffer(size, dynamic);
|
||||
}
|
||||
|
||||
void GrContext::setTexture(GrTexture* texture) {
|
||||
fGpu->setTexture(texture);
|
||||
void GrContext::setTexture(int stage, GrTexture* texture) {
|
||||
fGpu->setTexture(stage, texture);
|
||||
}
|
||||
|
||||
void GrContext::setRenderTarget(GrRenderTarget* target) {
|
||||
@ -858,12 +858,12 @@ void GrContext::setDefaultRenderTargetSize(uint32_t width, uint32_t height) {
|
||||
fGpu->setDefaultRenderTargetSize(width, height);
|
||||
}
|
||||
|
||||
void GrContext::setSamplerState(const GrSamplerState& samplerState) {
|
||||
fGpu->setSamplerState(samplerState);
|
||||
void GrContext::setSamplerState(int stage, const GrSamplerState& samplerState) {
|
||||
fGpu->setSamplerState(stage, samplerState);
|
||||
}
|
||||
|
||||
void GrContext::setTextureMatrix(const GrMatrix& m) {
|
||||
fGpu->setTextureMatrix(m);
|
||||
void GrContext::setTextureMatrix(int stage, const GrMatrix& m) {
|
||||
fGpu->setTextureMatrix(stage, m);
|
||||
}
|
||||
|
||||
void GrContext::getViewMatrix(GrMatrix* m) const {
|
||||
|
@ -18,93 +18,265 @@
|
||||
#include "GrDrawTarget.h"
|
||||
#include "GrGpuVertex.h"
|
||||
|
||||
#define VERTEX_LAYOUT_ASSERTS \
|
||||
GrAssert(!(vertexLayout & kTextFormat_VertexLayoutBit) || \
|
||||
vertexLayout == kTextFormat_VertexLayoutBit); \
|
||||
GrAssert(!(vertexLayout & kSeparateTexCoord_VertexLayoutBit) || \
|
||||
!(vertexLayout & kPositionAsTexCoord_VertexLayoutBit));
|
||||
// recursive helper for creating mask with all the tex coord bits set for
|
||||
// one stage
|
||||
template <int N>
|
||||
static int stage_mask_recur(int stage) {
|
||||
return GrDrawTarget::StageTexCoordVertexLayoutBit(stage, N) |
|
||||
stage_mask_recur<N+1>(stage);
|
||||
}
|
||||
template<>
|
||||
static int stage_mask_recur<GrDrawTarget::kNumStages>(int) { return 0; }
|
||||
|
||||
size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
|
||||
VERTEX_LAYOUT_ASSERTS
|
||||
if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
|
||||
return 2 * sizeof(GrGpuTextVertex);
|
||||
} else {
|
||||
size_t size = sizeof(GrPoint);
|
||||
if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
|
||||
size += sizeof(GrPoint);
|
||||
}
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
size += sizeof(GrColor);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
// mask of all tex coord indices for one stage
|
||||
static int stage_tex_coord_mask(int stage) {
|
||||
return stage_mask_recur<0>(stage);
|
||||
}
|
||||
|
||||
int GrDrawTarget::VertexTexCoordOffset(GrVertexLayout vertexLayout) {
|
||||
VERTEX_LAYOUT_ASSERTS
|
||||
if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
|
||||
return sizeof(GrGpuTextVertex);
|
||||
} else if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
|
||||
return sizeof(GrPoint);
|
||||
} else if (vertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
|
||||
// mask of all bits relevant to one stage
|
||||
static int stage_mask(int stage) {
|
||||
return stage_tex_coord_mask(stage) |
|
||||
GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(stage);
|
||||
}
|
||||
|
||||
// recursive helper for creating mask of with all bits set relevant to one
|
||||
// texture coordinate index
|
||||
template <int N>
|
||||
static int tex_coord_mask_recur(int texCoordIdx) {
|
||||
return GrDrawTarget::StageTexCoordVertexLayoutBit(N, texCoordIdx) |
|
||||
tex_coord_mask_recur<N+1>(texCoordIdx);
|
||||
}
|
||||
template<>
|
||||
static int tex_coord_mask_recur<GrDrawTarget::kMaxTexCoords>(int) { return 0; }
|
||||
|
||||
// mask of all bits relevant to one texture coordinate index
|
||||
static int tex_coord_idx_mask(int texCoordIdx) {
|
||||
return tex_coord_mask_recur<0>(texCoordIdx);
|
||||
}
|
||||
|
||||
bool check_layout(GrVertexLayout layout) {
|
||||
// can only have 1 or 0 bits set for each stage.
|
||||
for (int s = 0; s < GrDrawTarget::kNumStages; ++s) {
|
||||
int stageBits = layout & stage_mask(s);
|
||||
if (stageBits && !GrIsPow2(stageBits)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t GrDrawTarget::VertexSize(GrVertexLayout vertexLayout) {
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
|
||||
size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
|
||||
sizeof(GrGpuTextVertex) :
|
||||
sizeof(GrPoint);
|
||||
|
||||
size_t size = vecSize; // position
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
if (tex_coord_idx_mask(t) & vertexLayout) {
|
||||
size += vecSize;
|
||||
}
|
||||
}
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
size += sizeof(GrColor);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int GrDrawTarget::VertexStageCoordOffset(int stage, GrVertexLayout vertexLayout) {
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
if (StagePosAsTexCoordVertexLayoutBit(stage) & vertexLayout) {
|
||||
return 0;
|
||||
}
|
||||
int tcIdx = VertexTexCoordsForStage(stage, vertexLayout);
|
||||
if (tcIdx >= 0) {
|
||||
|
||||
int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
|
||||
sizeof(GrGpuTextVertex) :
|
||||
sizeof(GrPoint);
|
||||
int offset = vecSize; // position
|
||||
// figure out how many tex coordinates are present and precede this one.
|
||||
for (int t = 0; t < tcIdx; ++t) {
|
||||
if (tex_coord_idx_mask(t) & vertexLayout) {
|
||||
offset += vecSize;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GrDrawTarget::VertexColorOffset(GrVertexLayout vertexLayout) {
|
||||
VERTEX_LAYOUT_ASSERTS
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
|
||||
return 2 * sizeof(GrPoint);
|
||||
} else {
|
||||
return sizeof(GrPoint);
|
||||
int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
|
||||
sizeof(GrGpuTextVertex) :
|
||||
sizeof(GrPoint);
|
||||
int offset = vecSize; // position
|
||||
// figure out how many tex coordinates are present and precede this one.
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
if (tex_coord_idx_mask(t) & vertexLayout) {
|
||||
offset += vecSize;
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GrDrawTarget::VertexSizeAndOffsets(GrVertexLayout vertexLayout,
|
||||
int* texCoordOffset,
|
||||
int* colorOffset) {
|
||||
VERTEX_LAYOUT_ASSERTS
|
||||
int GrDrawTarget::VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,
|
||||
int texCoordOffsetsByIdx[kMaxTexCoords],
|
||||
int* colorOffset) {
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
|
||||
GrAssert(NULL != texCoordOffset);
|
||||
GrAssert(NULL != texCoordOffsetsByIdx);
|
||||
GrAssert(NULL != colorOffset);
|
||||
|
||||
if ((vertexLayout & kTextFormat_VertexLayoutBit)) {
|
||||
*texCoordOffset = sizeof(GrGpuTextVertex);
|
||||
*colorOffset = 0;
|
||||
return 2 * sizeof(GrGpuTextVertex);
|
||||
} else {
|
||||
size_t size = sizeof(GrPoint);
|
||||
if (vertexLayout & kSeparateTexCoord_VertexLayoutBit) {
|
||||
*texCoordOffset = sizeof(GrPoint);
|
||||
size += sizeof(GrPoint);
|
||||
} else if (vertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
|
||||
*texCoordOffset = 0;
|
||||
int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
|
||||
sizeof(GrGpuTextVertex) :
|
||||
sizeof(GrPoint);
|
||||
int size = vecSize; // position
|
||||
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
if (tex_coord_idx_mask(t) & vertexLayout) {
|
||||
texCoordOffsetsByIdx[t] = size;
|
||||
size += vecSize;
|
||||
} else {
|
||||
*texCoordOffset = -1;
|
||||
texCoordOffsetsByIdx[t] = -1;
|
||||
}
|
||||
if (vertexLayout & kColor_VertexLayoutBit) {
|
||||
*colorOffset = size;
|
||||
size += sizeof(GrColor);
|
||||
} else {
|
||||
*colorOffset = -1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
if (kColor_VertexLayoutBit & vertexLayout) {
|
||||
*colorOffset = size;
|
||||
size += sizeof(GrColor);
|
||||
} else {
|
||||
*colorOffset = -1;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool GrDrawTarget::VertexHasTexCoords(GrVertexLayout vertexLayout) {
|
||||
return !!(vertexLayout & (kSeparateTexCoord_VertexLayoutBit |
|
||||
kPositionAsTexCoord_VertexLayoutBit |
|
||||
kTextFormat_VertexLayoutBit));
|
||||
int GrDrawTarget::VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,
|
||||
int texCoordOffsetsByStage[kNumStages],
|
||||
int* colorOffset) {
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
|
||||
GrAssert(NULL != texCoordOffsetsByStage);
|
||||
GrAssert(NULL != colorOffset);
|
||||
|
||||
int texCoordOffsetsByIdx[kMaxTexCoords];
|
||||
int size = VertexSizeAndOffsetsByIdx(vertexLayout,
|
||||
texCoordOffsetsByIdx,
|
||||
colorOffset);
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
int tcIdx;
|
||||
if (StagePosAsTexCoordVertexLayoutBit(s) & vertexLayout) {
|
||||
texCoordOffsetsByStage[s] = 0;
|
||||
} else if ((tcIdx = VertexTexCoordsForStage(s, vertexLayout)) >= 0) {
|
||||
texCoordOffsetsByStage[s] = texCoordOffsetsByIdx[tcIdx];
|
||||
} else {
|
||||
texCoordOffsetsByStage[s] = -1;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool GrDrawTarget::VertexUsesStage(int stage, GrVertexLayout vertexLayout) {
|
||||
GrAssert(stage < kNumStages);
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
return !!(stage_mask(stage) & vertexLayout);
|
||||
}
|
||||
|
||||
bool GrDrawTarget::VertexUsesTexCoordIdx(int coordIndex,
|
||||
GrVertexLayout vertexLayout) {
|
||||
GrAssert(coordIndex < kMaxTexCoords);
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
return !!(tex_coord_idx_mask(coordIndex) & vertexLayout);
|
||||
}
|
||||
|
||||
int GrDrawTarget::VertexTexCoordsForStage(int stage, GrVertexLayout vertexLayout) {
|
||||
GrAssert(stage < kNumStages);
|
||||
GrAssert(check_layout(vertexLayout));
|
||||
int bit = vertexLayout & stage_tex_coord_mask(stage);
|
||||
if (bit) {
|
||||
// figure out which set of texture coordates is used
|
||||
// bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
|
||||
// and start at bit 0.
|
||||
GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
|
||||
return (32 - Gr_clz(bit) - 1) / kNumStages;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void GrDrawTarget::VertexLayoutUnitTest() {
|
||||
// not necessarily exhaustive
|
||||
static bool run;
|
||||
if (!run) {
|
||||
run = true;
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
|
||||
GrAssert(!VertexUsesStage(s, 0));
|
||||
GrAssert(-1 == VertexStageCoordOffset(s, 0));
|
||||
GrVertexLayout stageMask = 0;
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
stageMask |= StageTexCoordVertexLayoutBit(s,t);
|
||||
}
|
||||
GrAssert(1 == kMaxTexCoords || !check_layout(stageMask));
|
||||
GrAssert(stage_tex_coord_mask(s) == stageMask);
|
||||
stageMask |= StagePosAsTexCoordVertexLayoutBit(s);
|
||||
GrAssert(stage_mask(s) == stageMask);
|
||||
GrAssert(!check_layout(stageMask));
|
||||
}
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
GrVertexLayout tcMask = 0;
|
||||
GrAssert(!VertexUsesTexCoordIdx(t, 0));
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
tcMask |= StageTexCoordVertexLayoutBit(s,t);
|
||||
GrAssert(VertexUsesStage(s, tcMask));
|
||||
GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
|
||||
GrAssert(VertexUsesTexCoordIdx(t, tcMask));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
|
||||
GrAssert(t == VertexTexCoordsForStage(s, tcMask));
|
||||
for (int s2 = s + 1; s2 < kNumStages; ++s2) {
|
||||
GrAssert(-1 == VertexStageCoordOffset(s2, tcMask));
|
||||
GrAssert(!VertexUsesStage(s2, tcMask));
|
||||
GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
|
||||
|
||||
GrVertexLayout posAsTex = tcMask | StagePosAsTexCoordVertexLayoutBit(s2);
|
||||
GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
|
||||
GrAssert(VertexUsesStage(s2, posAsTex));
|
||||
GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
|
||||
GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
|
||||
}
|
||||
GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
|
||||
GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
|
||||
GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
|
||||
}
|
||||
GrAssert(tex_coord_idx_mask(t) == tcMask);
|
||||
GrAssert(check_layout(tcMask));
|
||||
|
||||
int stageOffsets[kNumStages];
|
||||
int colorOffset;
|
||||
int size;
|
||||
size = VertexSizeAndOffsetsByStage(tcMask, stageOffsets, &colorOffset);
|
||||
GrAssert(2*sizeof(GrPoint) == size);
|
||||
GrAssert(-1 == colorOffset);
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrAssert(VertexUsesStage(s, tcMask));
|
||||
GrAssert(sizeof(GrPoint) == stageOffsets[s]);
|
||||
GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrDrawTarget::GrDrawTarget() {
|
||||
#if GR_DEBUG
|
||||
VertexLayoutUnitTest();
|
||||
#endif
|
||||
fReservedGeometry.fLocked = false;
|
||||
#if GR_DEBUG
|
||||
fReservedGeometry.fVertexCount = ~0;
|
||||
@ -123,12 +295,14 @@ const GrClip& GrDrawTarget::getClip() const {
|
||||
return fClip;
|
||||
}
|
||||
|
||||
void GrDrawTarget::setTexture(GrTexture* tex) {
|
||||
fCurrDrawState.fTexture = tex;
|
||||
void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
|
||||
GrAssert(stage >= 0 && stage < kNumStages);
|
||||
fCurrDrawState.fTextures[stage] = tex;
|
||||
}
|
||||
|
||||
GrTexture* GrDrawTarget::currentTexture() const {
|
||||
return fCurrDrawState.fTexture;
|
||||
GrTexture* GrDrawTarget::currentTexture(int stage) const {
|
||||
GrAssert(stage >= 0 && stage < kNumStages);
|
||||
return fCurrDrawState.fTextures[stage];
|
||||
}
|
||||
|
||||
void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
|
||||
@ -139,21 +313,25 @@ GrRenderTarget* GrDrawTarget::currentRenderTarget() const {
|
||||
return fCurrDrawState.fRenderTarget;
|
||||
}
|
||||
|
||||
void GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) {
|
||||
GrMatrix mv;
|
||||
mv.setConcat(fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode], matrix);
|
||||
this->loadMatrix(mv, kModelView_MatrixMode);
|
||||
void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
|
||||
fCurrDrawState.fViewMatrix = m;
|
||||
}
|
||||
|
||||
void GrDrawTarget::concatViewMatrix(const GrMatrix& matrix) {
|
||||
fCurrDrawState.fViewMatrix.preConcat(matrix);
|
||||
}
|
||||
|
||||
// Can't this just return a const&
|
||||
void GrDrawTarget::getViewMatrix(GrMatrix* matrix) const {
|
||||
*matrix = fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
|
||||
*matrix = fCurrDrawState.fViewMatrix;
|
||||
}
|
||||
|
||||
bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
|
||||
// Can we cache this somewhere?
|
||||
// Mike: Can we cache this somewhere?
|
||||
// Brian: Sure, do we use it often?
|
||||
|
||||
GrMatrix inverse;
|
||||
if (fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode].invert(&inverse)) {
|
||||
if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
|
||||
if (matrix) {
|
||||
*matrix = inverse;
|
||||
}
|
||||
@ -162,8 +340,14 @@ bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GrDrawTarget::setSamplerState(const GrSamplerState& state) {
|
||||
fCurrDrawState.fSamplerState = state;
|
||||
void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
|
||||
GrAssert(stage >= 0 && stage < kNumStages);
|
||||
fCurrDrawState.fSamplerStates[stage] = state;
|
||||
}
|
||||
|
||||
void GrDrawTarget::setTextureMatrix(int stage, const GrMatrix& m) {
|
||||
GrAssert(stage >= 0 && stage < kNumStages);
|
||||
fCurrDrawState.fTextureMatrices[stage] = m;
|
||||
}
|
||||
|
||||
void GrDrawTarget::setStencilPass(StencilPass pass) {
|
||||
@ -182,10 +366,6 @@ void GrDrawTarget::disableState(uint32_t bits) {
|
||||
fCurrDrawState.fFlagBits &= ~(bits);
|
||||
}
|
||||
|
||||
void GrDrawTarget::loadMatrix(const GrMatrix& matrix, MatrixMode m) {
|
||||
fCurrDrawState.fMatrixModeCache[m] = matrix;
|
||||
}
|
||||
|
||||
void GrDrawTarget::setPointSize(float size) {
|
||||
fCurrDrawState.fPointSize = size;
|
||||
}
|
||||
|
@ -144,6 +144,9 @@ void GrGLTexture::uploadTextureData(uint32_t x,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
const void* srcData) {
|
||||
|
||||
fGpuGL->setSpareTextureUnit();
|
||||
|
||||
// glCompressedTexSubImage2D doesn't support any formats
|
||||
// (at least without extensions)
|
||||
GrAssert(fUploadFormat != GR_PALETTE8_RGBA8);
|
||||
@ -152,7 +155,6 @@ void GrGLTexture::uploadTextureData(uint32_t x,
|
||||
// then we have to modify this code to flip the srcData
|
||||
GrAssert(kTopDown_Orientation == fOrientation);
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID));
|
||||
fGpuGL->notifyTextureBind(this);
|
||||
GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, fUploadByteCount));
|
||||
GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
|
||||
fUploadFormat, fUploadType, srcData));
|
||||
|
@ -92,20 +92,32 @@ bool GrGpu::canDisableBlend() const {
|
||||
}
|
||||
|
||||
// If the src coef will always be 1...
|
||||
bool fullSrc = kSA_BlendCoeff == fCurrDrawState.fSrcBlend ||
|
||||
kOne_BlendCoeff == fCurrDrawState.fSrcBlend;
|
||||
if (kSA_BlendCoeff != fCurrDrawState.fSrcBlend &&
|
||||
kOne_BlendCoeff != fCurrDrawState.fSrcBlend) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...and the dst coef is always 0...
|
||||
bool noDst = kISA_BlendCoeff == fCurrDrawState.fDstBlend ||
|
||||
kZero_BlendCoeff == fCurrDrawState.fDstBlend;
|
||||
if (kISA_BlendCoeff != fCurrDrawState.fDstBlend &&
|
||||
kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...and there isn't a texture with an alpha channel...
|
||||
bool noTexAlpha = !VertexHasTexCoords(fGeometrySrc.fVertexLayout) ||
|
||||
fCurrDrawState.fTexture->config() == GrTexture::kRGB_565_PixelConfig ||
|
||||
fCurrDrawState.fTexture->config() == GrTexture::kRGBX_8888_PixelConfig;
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (VertexUsesStage(s, fGeometrySrc.fVertexLayout)) {
|
||||
GrAssert(NULL != fCurrDrawState.fTextures[s]);
|
||||
GrTexture::PixelConfig config = fCurrDrawState.fTextures[s]->config();
|
||||
|
||||
if (GrTexture::kRGB_565_PixelConfig != config &&
|
||||
GrTexture::kRGBX_8888_PixelConfig != config) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ...then we disable blend.
|
||||
return fullSrc && noDst && noTexAlpha;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -29,6 +29,10 @@
|
||||
static const GLuint GR_MAX_GLUINT = ~0;
|
||||
static const GLint GR_INVAL_GLINT = ~0;
|
||||
|
||||
// we use a spare texture unit to avoid
|
||||
// mucking with the state of any of the stages.
|
||||
static const int SPARE_TEX_UNIT = GrGpuGL::kNumStages;
|
||||
|
||||
#define SKIP_CACHE_CHECK true
|
||||
|
||||
static const GLenum gXfermodeCoeff2Blend[] = {
|
||||
@ -69,7 +73,7 @@ void gl_version(int* major, int* minor) {
|
||||
*minor = 0;
|
||||
return;
|
||||
}
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
int n = sscanf(v, "%d.%d", major, minor);
|
||||
if (n != 2) {
|
||||
GrAssert(0);
|
||||
@ -96,6 +100,14 @@ void gl_version(int* major, int* minor) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool fbo_test(GrGLExts exts, int w, int h) {
|
||||
|
||||
GLint savedFBO;
|
||||
GLint savedTexUnit;
|
||||
GR_GL(GetIntegerv(GL_ACTIVE_TEXTURE, &savedTexUnit));
|
||||
GR_GL(GetIntegerv(GR_FRAMEBUFFER_BINDING, &savedFBO));
|
||||
|
||||
GR_GL(ActiveTexture(GL_TEXTURE0 + SPARE_TEX_UNIT));
|
||||
|
||||
GLuint testFBO;
|
||||
GR_GLEXT(exts, GenFramebuffers(1, &testFBO));
|
||||
GR_GLEXT(exts, BindFramebuffer(GR_FRAMEBUFFER, testFBO));
|
||||
@ -113,6 +125,10 @@ bool fbo_test(GrGLExts exts, int w, int h) {
|
||||
GLenum status = GR_GLEXT(exts, CheckFramebufferStatus(GR_FRAMEBUFFER));
|
||||
GR_GLEXT(exts, DeleteFramebuffers(1, &testFBO));
|
||||
GR_GL(DeleteTextures(1, &testRTTex));
|
||||
|
||||
GR_GL(ActiveTexture(savedTexUnit));
|
||||
GR_GLEXT(exts, BindFramebuffer(GR_FRAMEBUFFER, savedFBO));
|
||||
|
||||
return status == GR_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
@ -156,6 +172,19 @@ GrGpuGL::GrGpuGL() {
|
||||
fHWDrawState.fRenderTarget = fDefaultRenderTarget;
|
||||
fRenderTargetChanged = true;
|
||||
|
||||
GLint maxTextureUnits;
|
||||
// check FS and fixed-function texture unit limits
|
||||
// we only use textures in the fragment stage currently.
|
||||
// checks are > to make sure we have a spare unit.
|
||||
#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES2
|
||||
GR_GL(GetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits));
|
||||
GrAssert(maxTextureUnits > kNumStages);
|
||||
#endif
|
||||
#if GR_SUPPORT_GLDESKTOP || GR_SUPPORT_GLES1
|
||||
GR_GL(GetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextureUnits));
|
||||
GrAssert(maxTextureUnits > kNumStages);
|
||||
#endif
|
||||
|
||||
fCurrDrawState = fHWDrawState;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -198,7 +227,7 @@ GrGpuGL::GrGpuGL() {
|
||||
GrPrintf("MSAA Support: APPLE ES EXT.\n");
|
||||
}
|
||||
}
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
else if ((major >= 3) ||
|
||||
has_gl_extension("GL_ARB_framebuffer_object") ||
|
||||
(has_gl_extension("GL_EXT_framebuffer_multisample") &&
|
||||
@ -236,7 +265,7 @@ GrGpuGL::GrGpuGL() {
|
||||
}
|
||||
}
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
fHasStencilWrap = (major >= 2 || (major == 1 && minor >= 4)) ||
|
||||
has_gl_extension("GL_EXT_stencil_wrap");
|
||||
#else
|
||||
@ -246,7 +275,7 @@ GrGpuGL::GrGpuGL() {
|
||||
GrPrintf("Stencil Wrap: %s\n", (fHasStencilWrap ? "YES" : "NO"));
|
||||
}
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
// we could also look for GL_ATI_separate_stencil extension or
|
||||
// GL_EXT_stencil_two_side but they use different function signatures
|
||||
// than GL2.0+ (and than each other).
|
||||
@ -261,7 +290,7 @@ GrGpuGL::GrGpuGL() {
|
||||
}
|
||||
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
fRGBA8Renderbuffer = true;
|
||||
#else
|
||||
fRGBA8Renderbuffer = has_gl_extension("GL_OES_rgb8_rgba8");
|
||||
@ -271,7 +300,7 @@ GrGpuGL::GrGpuGL() {
|
||||
}
|
||||
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
fBufferLockSupport = true; // we require VBO support and the desktop VBO
|
||||
// extension includes glMapBuffer.
|
||||
#else
|
||||
@ -281,7 +310,7 @@ GrGpuGL::GrGpuGL() {
|
||||
GrPrintf("Map Buffer: %s\n", (fBufferLockSupport ? "YES" : "NO"));
|
||||
}
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
fNPOTTextureSupport =
|
||||
(major >= 2 || has_gl_extension("GL_ARB_texture_non_power_of_two")) ?
|
||||
kFull_NPOTTextureType :
|
||||
@ -433,7 +462,7 @@ void GrGpuGL::resetContextHelper() {
|
||||
GR_GL(Disable(GL_CULL_FACE));
|
||||
|
||||
GR_GL(Disable(GL_DITHER));
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
GR_GL(Disable(GL_LINE_SMOOTH));
|
||||
GR_GL(Disable(GL_POINT_SMOOTH));
|
||||
GR_GL(Disable(GL_MULTISAMPLE));
|
||||
@ -442,7 +471,8 @@ void GrGpuGL::resetContextHelper() {
|
||||
// we only ever use lines in hairline mode
|
||||
GR_GL(LineWidth(1));
|
||||
|
||||
GR_GL(ActiveTexture(GL_TEXTURE0));
|
||||
// invalid
|
||||
fActiveTextureUnitIdx = -1;
|
||||
|
||||
fHWDrawState.fFlagBits = 0;
|
||||
|
||||
@ -451,21 +481,22 @@ void GrGpuGL::resetContextHelper() {
|
||||
fHWDrawState.fDstBlend = (BlendCoeff)-1;
|
||||
fHWDrawState.fColor = GrColor_ILLEGAL;
|
||||
fHWDrawState.fPointSize = -1;
|
||||
fHWDrawState.fTexture = NULL;
|
||||
|
||||
fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax); // illegal
|
||||
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
fHWDrawState.fTextures[s] = NULL;
|
||||
fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax,
|
||||
-GR_ScalarMax,
|
||||
true);
|
||||
fHWDrawState.fTextureMatrices[s].setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
}
|
||||
|
||||
GR_GL(Scissor(0,0,0,0));
|
||||
fHWBounds.fScissorRect.setLTRB(0,0,0,0);
|
||||
fHWBounds.fScissorEnabled = false;
|
||||
GR_GL(Disable(GL_SCISSOR_TEST));
|
||||
|
||||
fHWDrawState.fSamplerState.setRadial2Params(-GR_ScalarMax,
|
||||
-GR_ScalarMax,
|
||||
true);
|
||||
|
||||
for (int i = 0; i < kMatrixModeCount; i++) {
|
||||
fHWDrawState.fMatrixModeCache[i].setScale(GR_ScalarMax, GR_ScalarMax); // illegal
|
||||
}
|
||||
|
||||
// disabling the stencil test also disables
|
||||
// stencil buffer writes
|
||||
GR_GL(Disable(GL_STENCIL_TEST));
|
||||
@ -490,7 +521,7 @@ void GrGpuGL::resetContext() {
|
||||
|
||||
|
||||
// defines stencil formats from more to less preferred
|
||||
#if GR_GL_ES
|
||||
#if GR_SUPPORT_GLES
|
||||
GLenum GR_GL_STENCIL_FORMAT_ARRAY[] = {
|
||||
GR_STENCIL_INDEX8,
|
||||
};
|
||||
@ -544,6 +575,8 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
++fStats.fTextureCreateCnt;
|
||||
#endif
|
||||
|
||||
setSpareTextureUnit();
|
||||
|
||||
static const GrGLTexture::TexParams DEFAULT_PARAMS = {
|
||||
GL_NEAREST,
|
||||
GL_CLAMP_TO_EDGE,
|
||||
@ -585,7 +618,7 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
* to trim those off here, since GL doesn't let us pass the rowBytes as
|
||||
* a parameter to glTexImage2D
|
||||
*/
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
if (srcData) {
|
||||
GR_GL(PixelStorei(GL_UNPACK_ROW_LENGTH,
|
||||
rowBytes / glDesc.fUploadByteCount));
|
||||
@ -636,10 +669,6 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
DEFAULT_PARAMS.fWrapT));
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
fHWDrawState.fTexture = NULL;
|
||||
|
||||
GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, glDesc.fUploadByteCount));
|
||||
if (GrTexture::kIndex_8_PixelConfig == desc.fFormat &&
|
||||
@ -763,7 +792,6 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
GR_GL(DeleteTextures(1, &glDesc.fTextureID));
|
||||
GR_GLEXT(fExts, DeleteFramebuffers(1, &rtIDs.fTexFBOID));
|
||||
GR_GLEXT(fExts, DeleteFramebuffers(1, &rtIDs.fRTFBOID));
|
||||
fHWDrawState.fTexture = NULL;
|
||||
return return_null_texture();
|
||||
}
|
||||
} else {
|
||||
@ -776,12 +804,10 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
attempts = GR_ARRAY_COUNT(GR_GL_STENCIL_FORMAT_ARRAY);
|
||||
}
|
||||
|
||||
// need to unbind the texture before we call FramebufferTexture2D
|
||||
// someone suggested that some systems might require
|
||||
// unbinding the texture before we call FramebufferTexture2D
|
||||
// (seems unlikely)
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, 0));
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
GrAssert(NULL == fHWDrawState.fTexture);
|
||||
|
||||
err = ~GL_NO_ERROR;
|
||||
for (int i = 0; i < attempts; ++i) {
|
||||
@ -869,7 +895,7 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
}
|
||||
status = GR_GLEXT(fExts, CheckFramebufferStatus(GR_FRAMEBUFFER));
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
// On some implementations you have to be bound as DEPTH_STENCIL.
|
||||
// (Even binding to DEPTH and STENCIL separately with the same
|
||||
// buffer doesn't work.)
|
||||
@ -890,7 +916,7 @@ GrTexture* GrGpuGL::createTexture(const TextureDesc& desc,
|
||||
if (status != GR_FRAMEBUFFER_COMPLETE) {
|
||||
GrPrintf("-- glCheckFramebufferStatus %x %d %d\n",
|
||||
status, desc.fWidth, desc.fHeight);
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
if (rtIDs.fStencilRenderbufferID) {
|
||||
GR_GLEXT(fExts, FramebufferRenderbuffer(GR_FRAMEBUFFER,
|
||||
GR_DEPTH_STENCIL_ATTACHMENT,
|
||||
@ -1428,65 +1454,75 @@ void GrGpuGL::flushStencil() {
|
||||
|
||||
void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
|
||||
bool usingTexture = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
bool usingTexture = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
|
||||
|
||||
// bind texture and set sampler state
|
||||
if (usingTexture) {
|
||||
GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTexture;
|
||||
// bind texture and set sampler state
|
||||
if (usingTexture) {
|
||||
GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTextures[s];
|
||||
|
||||
if (NULL != nextTexture) {
|
||||
// if we created a rt/tex and rendered to it without using a texture
|
||||
// and now we're texuring from the rt it will still be the last bound
|
||||
// texture, but it needs resolving. So keep this out of the last
|
||||
// != next check.
|
||||
resolveTextureRenderTarget(nextTexture);
|
||||
if (NULL != nextTexture) {
|
||||
// if we created a rt/tex and rendered to it without using a
|
||||
// texture and now we're texuring from the rt it will still be
|
||||
// the last bound texture, but it needs resolving. So keep this
|
||||
// out of the "last != next" check.
|
||||
resolveTextureRenderTarget(nextTexture);
|
||||
|
||||
if (fHWDrawState.fTexture != nextTexture) {
|
||||
if (fHWDrawState.fTextures[s] != nextTexture) {
|
||||
setTextureUnit(s);
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, nextTexture->textureID()));
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
//GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
|
||||
fHWDrawState.fTextures[s] = nextTexture;
|
||||
}
|
||||
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, nextTexture->textureID()));
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
//GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
|
||||
fHWDrawState.fTexture = nextTexture;
|
||||
}
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
|
||||
const GrGLTexture::TexParams& oldTexParams =
|
||||
nextTexture->getTexParams();
|
||||
GrGLTexture::TexParams newTexParams;
|
||||
|
||||
const GrGLTexture::TexParams& oldTexParams = nextTexture->getTexParams();
|
||||
GrGLTexture::TexParams newTexParams;
|
||||
newTexParams.fFilter = fCurrDrawState.fSamplerState.isFilter() ?
|
||||
GL_LINEAR :
|
||||
GL_NEAREST;
|
||||
newTexParams.fWrapS = GrGLTexture::gWrapMode2GLWrap[fCurrDrawState.fSamplerState.getWrapX()];
|
||||
newTexParams.fWrapT = GrGLTexture::gWrapMode2GLWrap[fCurrDrawState.fSamplerState.getWrapY()];
|
||||
newTexParams.fFilter = sampler.isFilter() ? GL_LINEAR :
|
||||
GL_NEAREST;
|
||||
newTexParams.fWrapS =
|
||||
GrGLTexture::gWrapMode2GLWrap[sampler.getWrapX()];
|
||||
newTexParams.fWrapT =
|
||||
GrGLTexture::gWrapMode2GLWrap[sampler.getWrapY()];
|
||||
|
||||
if (newTexParams.fFilter != oldTexParams.fFilter) {
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MAG_FILTER,
|
||||
newTexParams.fFilter));
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
newTexParams.fFilter));
|
||||
}
|
||||
if (newTexParams.fWrapS != oldTexParams.fWrapS) {
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S,
|
||||
newTexParams.fWrapS));
|
||||
}
|
||||
if (newTexParams.fWrapT != oldTexParams.fWrapT) {
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
newTexParams.fWrapT));
|
||||
}
|
||||
nextTexture->setTexParams(newTexParams);
|
||||
} else {
|
||||
GrAssert(!"Rendering with texture vert flag set but no texture");
|
||||
if (NULL != fHWDrawState.fTexture) {
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, 0));
|
||||
// GrPrintf("---- bindtexture 0\n");
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
fHWDrawState.fTexture = NULL;
|
||||
if (newTexParams.fFilter != oldTexParams.fFilter) {
|
||||
setTextureUnit(s);
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MAG_FILTER,
|
||||
newTexParams.fFilter));
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_MIN_FILTER,
|
||||
newTexParams.fFilter));
|
||||
}
|
||||
if (newTexParams.fWrapS != oldTexParams.fWrapS) {
|
||||
setTextureUnit(s);
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_S,
|
||||
newTexParams.fWrapS));
|
||||
}
|
||||
if (newTexParams.fWrapT != oldTexParams.fWrapT) {
|
||||
setTextureUnit(s);
|
||||
GR_GL(TexParameteri(GL_TEXTURE_2D,
|
||||
GL_TEXTURE_WRAP_T,
|
||||
newTexParams.fWrapT));
|
||||
}
|
||||
nextTexture->setTexParams(newTexParams);
|
||||
} else {
|
||||
GrAssert(!"Rendering with texture vert flag set but no texture");
|
||||
if (NULL != fHWDrawState.fTextures[s]) {
|
||||
setTextureUnit(s);
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, 0));
|
||||
// GrPrintf("---- bindtexture 0\n");
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
fHWDrawState.fTextures[s] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1502,7 +1538,7 @@ void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
}
|
||||
}
|
||||
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
// ES doesn't support toggling GL_MULTISAMPLE and doesn't have
|
||||
// smooth lines.
|
||||
if (fRenderTargetChanged ||
|
||||
@ -1550,11 +1586,16 @@ void GrGpuGL::flushGLStateCommon(PrimitiveType type) {
|
||||
}
|
||||
}
|
||||
|
||||
#if GR_DEBUG
|
||||
// check for circular rendering
|
||||
GrAssert(!usingTexture ||
|
||||
NULL == fCurrDrawState.fRenderTarget ||
|
||||
NULL == fCurrDrawState.fTexture ||
|
||||
fCurrDrawState.fTexture->asRenderTarget() != fCurrDrawState.fRenderTarget);
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrAssert(!VertexUsesStage(s, fGeometrySrc.fVertexLayout) ||
|
||||
NULL == fCurrDrawState.fRenderTarget ||
|
||||
NULL == fCurrDrawState.fTextures[s] ||
|
||||
fCurrDrawState.fTextures[s]->asRenderTarget() !=
|
||||
fCurrDrawState.fRenderTarget);
|
||||
}
|
||||
#endif
|
||||
|
||||
flushStencil();
|
||||
|
||||
@ -1589,13 +1630,6 @@ void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::notifyTextureBind(GrGLTexture* texture) {
|
||||
fHWDrawState.fTexture = texture;
|
||||
#if GR_COLLECT_STATS
|
||||
++fStats.fTextureChngCnt;
|
||||
#endif
|
||||
}
|
||||
|
||||
void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
|
||||
GrAssert(NULL != renderTarget);
|
||||
|
||||
@ -1615,13 +1649,15 @@ void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
|
||||
}
|
||||
|
||||
void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
|
||||
if (fCurrDrawState.fTexture == texture) {
|
||||
fCurrDrawState.fTexture = NULL;
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (fCurrDrawState.fTextures[s] == texture) {
|
||||
fCurrDrawState.fTextures[s] = NULL;
|
||||
}
|
||||
if (fHWDrawState.fTextures[s] == texture) {
|
||||
// deleting bound texture does implied bind to 0
|
||||
fHWDrawState.fTextures[s] = NULL;
|
||||
}
|
||||
}
|
||||
if (fHWDrawState.fTexture == texture) {
|
||||
// deleting bound texture does implied bind to 0
|
||||
fHWDrawState.fTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::notifyTextureRemoveRenderTarget(GrGLTexture* texture) {
|
||||
@ -1672,6 +1708,21 @@ bool GrGpuGL::canBeTexture(GrTexture::PixelConfig config,
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrGpuGL::setTextureUnit(int unit) {
|
||||
GrAssert(unit >= 0 && unit < kNumStages);
|
||||
if (fActiveTextureUnitIdx != unit) {
|
||||
GR_GL(ActiveTexture(GL_TEXTURE0 + unit));
|
||||
fActiveTextureUnitIdx = unit;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::setSpareTextureUnit() {
|
||||
if (fActiveTextureUnitIdx != (GL_TEXTURE0 + SPARE_TEX_UNIT)) {
|
||||
GR_GL(ActiveTexture(GL_TEXTURE0 + SPARE_TEX_UNIT));
|
||||
fActiveTextureUnitIdx = SPARE_TEX_UNIT;
|
||||
}
|
||||
}
|
||||
|
||||
/* On ES the internalFormat and format must match for TexImage and we use
|
||||
GL_RGB, GL_RGBA for color formats. We also generally like having the driver
|
||||
decide the internalFormat. However, on ES internalFormat for
|
||||
@ -1688,8 +1739,8 @@ bool GrGpuGL::fboInternalFormat(GrTexture::PixelConfig config, GLenum* format) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#if GR_GL_ES // ES2 supports 565. ES1 supports it with FBO extension
|
||||
// desktop GL has no such internal format
|
||||
#if GR_SUPPORT_GLES // ES2 supports 565. ES1 supports it with FBO extension
|
||||
// desktop GL has no such internal format
|
||||
case GrTexture::kRGB_565_PixelConfig:
|
||||
*format = GR_RGB565;
|
||||
return true;
|
||||
@ -1799,7 +1850,7 @@ extern void GrGLInitExtensions(GrGLExts* exts) {
|
||||
#else
|
||||
GLint major, minor;
|
||||
gl_version(&major, &minor);
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
if (major >= 3) {// FBO, FBOMS, and FBOBLIT part of 3.0
|
||||
exts->GenFramebuffers = glGenFramebuffers;
|
||||
exts->BindFramebuffer = glBindFramebuffer;
|
||||
@ -1849,7 +1900,7 @@ extern void GrGLInitExtensions(GrGLExts* exts) {
|
||||
// we assume we have at least GL 1.5 or higher (VBOs introduced in 1.5)
|
||||
exts->MapBuffer = glMapBuffer;
|
||||
exts->UnmapBuffer = glUnmapBuffer;
|
||||
#else // !GR_GL_DESKTOP
|
||||
#else // !GR_SUPPORT_GLDESKTOP
|
||||
if (major >= 2) {// ES 2.0 supports FBO
|
||||
exts->GenFramebuffers = glGenFramebuffers;
|
||||
exts->BindFramebuffer = glBindFramebuffer;
|
||||
@ -1886,7 +1937,7 @@ extern void GrGLInitExtensions(GrGLExts* exts) {
|
||||
GET_PROC(exts, MapBuffer, OES);
|
||||
GET_PROC(exts, UnmapBuffer, OES);
|
||||
}
|
||||
#endif // !GR_GL_DESKTOP
|
||||
#endif // !GR_SUPPORT_GLDESKTOP
|
||||
#endif // BUILD
|
||||
}
|
||||
|
||||
|
@ -88,6 +88,8 @@ protected:
|
||||
void eraseStencil(uint32_t value, uint32_t mask);
|
||||
virtual void eraseStencilClip();
|
||||
|
||||
void setTextureUnit(int unitIdx);
|
||||
|
||||
// flushes state that is common to fixed and programmable GL
|
||||
// dither
|
||||
// line smoothing
|
||||
@ -109,9 +111,9 @@ protected:
|
||||
// last scissor / viewport scissor state seen by the GL.
|
||||
BoundsState fHWBounds;
|
||||
|
||||
private:
|
||||
GrGLExts fExts;
|
||||
|
||||
private:
|
||||
GrGLRenderTarget* fDefaultRenderTarget;
|
||||
|
||||
void resetContextHelper();
|
||||
@ -122,11 +124,12 @@ private:
|
||||
void notifyVertexBufferDelete(const GrGLVertexBuffer* buffer);
|
||||
void notifyIndexBufferBind(const GrGLIndexBuffer* buffer);
|
||||
void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer);
|
||||
void notifyTextureBind(GrGLTexture* texture);
|
||||
void notifyTextureDelete(GrGLTexture* texture);
|
||||
void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
|
||||
void notifyTextureRemoveRenderTarget(GrGLTexture* texture);
|
||||
|
||||
void setSpareTextureUnit();
|
||||
|
||||
void flushRenderTarget();
|
||||
void flushStencil();
|
||||
void resolveTextureRenderTarget(GrGLTexture* texture);
|
||||
@ -158,6 +161,8 @@ private:
|
||||
// ES requires an extension to support RGBA8 in RenderBufferStorage
|
||||
bool fRGBA8Renderbuffer;
|
||||
|
||||
int fActiveTextureUnitIdx;
|
||||
|
||||
typedef GrGpu INHERITED;
|
||||
};
|
||||
|
||||
@ -168,7 +173,7 @@ void gl_version(int* major, int* minor);
|
||||
* GrGL_RestoreResetRowLength() will reset GL_UNPACK_ROW_LENGTH to 0. We write
|
||||
* this wrapper, since GL_UNPACK_ROW_LENGTH is not available on all GL versions
|
||||
*/
|
||||
#if GR_GL_DESKTOP
|
||||
#if GR_SUPPORT_GLDESKTOP
|
||||
static inline void GrGL_RestoreResetRowLength() {
|
||||
GR_GL(PixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
}
|
||||
|
@ -72,25 +72,27 @@ void GrGpuGLFixed::resetContext() {
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
|
||||
// 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));
|
||||
// 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.fPositionPtr = (void*) ~0;
|
||||
@ -127,11 +129,15 @@ void GrGpuGLFixed::flushProjectionMatrix() {
|
||||
|
||||
bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
|
||||
|
||||
bool usingTexture = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
|
||||
bool usingTextures[kNumStages];
|
||||
|
||||
if (usingTexture && fCurrDrawState.fSamplerState.isGradient()) {
|
||||
unimpl("Fixed pipe doesn't support radial/sweep gradients");
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
flushGLStateCommon(type);
|
||||
@ -141,12 +147,15 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
|
||||
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));
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,8 +165,6 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
|
||||
|
||||
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;
|
||||
@ -181,57 +188,61 @@ bool GrGpuGLFixed::flushGraphicsState(PrimitiveType type) {
|
||||
}
|
||||
|
||||
// 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]);
|
||||
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;
|
||||
}
|
||||
GR_GL(MatrixMode(gMatrixMode2Enum[kTexture_MatrixMode]));
|
||||
GR_GL(LoadMatrixf(glm.fMat));
|
||||
fHWDrawState.fMatrixModeCache[kTexture_MatrixMode] =
|
||||
fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
|
||||
fHWTextureOrientation = texture->orientation();
|
||||
|
||||
if (fHWTextureOrientation != texture->orientation() ||
|
||||
fHWDrawState.fTextureMatrices[s] !=
|
||||
fCurrDrawState.fTextureMatrices[s]) {
|
||||
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.fTextureMatrices[s]);
|
||||
glm.set(m);
|
||||
} else {
|
||||
glm.set(fCurrDrawState.fTextureMatrices[s]);
|
||||
}
|
||||
setTextureUnit(s);
|
||||
GR_GL(MatrixMode(GL_TEXTURE));
|
||||
GR_GL(LoadMatrixf(glm.fMat));
|
||||
fHWDrawState.fTextureMatrices[s] =
|
||||
fCurrDrawState.fTextureMatrices[s];
|
||||
fHWTextureOrientation = texture->orientation();
|
||||
}
|
||||
} else {
|
||||
GrAssert(!"Rendering with texture vert flag set but no bound texture");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
GrAssert(!"Rendering with texture vert flag set but no bound texture");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (fHWDrawState.fMatrixModeCache[kModelView_MatrixMode] !=
|
||||
fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
|
||||
if (fHWDrawState.fViewMatrix != fCurrDrawState.fViewMatrix) {
|
||||
GrGpuMatrix glm;
|
||||
glm.set(fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
|
||||
GR_GL(MatrixMode(gMatrixMode2Enum[kModelView_MatrixMode]));
|
||||
glm.set(fCurrDrawState.fViewMatrix);
|
||||
GR_GL(MatrixMode(GL_MODELVIEW));
|
||||
GR_GL(LoadMatrixf(glm.fMat));
|
||||
fHWDrawState.fMatrixModeCache[kModelView_MatrixMode] =
|
||||
fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
|
||||
fHWDrawState.fViewMatrix =
|
||||
fCurrDrawState.fViewMatrix;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -241,15 +252,17 @@ void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
|
||||
uint32_t vertexCount,
|
||||
uint32_t indexCount) {
|
||||
|
||||
int newColorOffset, newTexCoordOffset;
|
||||
int newColorOffset;
|
||||
int newTexCoordOffsets[kNumStages];
|
||||
|
||||
GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
|
||||
&newTexCoordOffset,
|
||||
&newColorOffset);
|
||||
int oldColorOffset, oldTexCoordOffset;
|
||||
GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
|
||||
&oldTexCoordOffset,
|
||||
&oldColorOffset);
|
||||
GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
|
||||
newTexCoordOffsets,
|
||||
&newColorOffset);
|
||||
int oldColorOffset;
|
||||
int oldTexCoordOffsets[kNumStages];
|
||||
GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
|
||||
oldTexCoordOffsets,
|
||||
&oldColorOffset);
|
||||
|
||||
const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
|
||||
|
||||
@ -258,7 +271,7 @@ void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
|
||||
GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
|
||||
if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
|
||||
GrGLVertexBuffer* buf =
|
||||
(GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
|
||||
(GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
|
||||
GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
|
||||
fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
|
||||
}
|
||||
@ -310,17 +323,23 @@ void GrGpuGLFixed::setupGeometry(uint32_t startVertex,
|
||||
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));
|
||||
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* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[s];
|
||||
if (oldTexCoordOffsets[s] < 0) {
|
||||
GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
|
||||
GR_GL(EnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
}
|
||||
if (posChange || newTexCoordOffsets[s] != oldTexCoordOffsets[s]) {
|
||||
GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
|
||||
GR_GL(TexCoordPointer(2, scalarType, newStride, texCoordPtr));
|
||||
}
|
||||
} else if (oldTexCoordOffsets[s] >= 0) {
|
||||
GR_GL(ClientActiveTexture(GL_TEXTURE0+s));
|
||||
GR_GL(DisableClientState(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) {
|
||||
|
@ -40,15 +40,15 @@ private:
|
||||
void resetContextHelper();
|
||||
|
||||
// when the texture is GL_RGBA we set the GL_COMBINE texture
|
||||
// environment rgb operand 0 to be GL_COLOR to modulate each incoming frag's
|
||||
// RGB by the texture's RGB. When the texture is GL_ALPHA we set
|
||||
// the operand to GL_ALPHA so that the incoming frag's RGB is modulated
|
||||
// by the texture's alpha.
|
||||
// environment rgb operand 0 to be GL_COLOR to modulate each incoming
|
||||
// R,G, & B by the texture's R, G, & B. When the texture is alpha-only we
|
||||
// set the operand to GL_ALPHA so that the incoming frag's R, G, &B are all
|
||||
// modulated by the texture's A.
|
||||
enum TextureEnvRGBOperands {
|
||||
kAlpha_TextureEnvRGBOperand,
|
||||
kColor_TextureEnvRGBOperand,
|
||||
};
|
||||
TextureEnvRGBOperands fHWRGBOperand0;
|
||||
TextureEnvRGBOperands fHWRGBOperand0[kNumStages];
|
||||
|
||||
void flushProjectionMatrix();
|
||||
|
||||
|
@ -512,8 +512,9 @@ GrGpuGLShaders::GrGpuGLShaders() {
|
||||
&fPrograms[p]);
|
||||
GR_DEBUGASSERT(result);
|
||||
|
||||
for (int m = 0; m < kMatrixModeCount; ++m) {
|
||||
fPrograms[p].fMatrixModeCache[m].setScale(GR_ScalarMax,
|
||||
fPrograms[p].fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
fPrograms[p].fTextureMatrices[s].setScale(GR_ScalarMax,
|
||||
GR_ScalarMax); // illegal
|
||||
};
|
||||
fPrograms[p].fColor = GrColor_ILLEGAL;
|
||||
@ -559,7 +560,7 @@ void GrGpuGLShaders::flushMatrix(GLint location) {
|
||||
GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
|
||||
0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
|
||||
0, 0, GrMatrix::I()[8]);
|
||||
m.setConcat(m, fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
|
||||
m.setConcat(m, fCurrDrawState.fViewMatrix);
|
||||
|
||||
// ES doesn't allow you to pass true to the transpose param,
|
||||
// so do our own transpose
|
||||
@ -593,11 +594,11 @@ void GrGpuGLShaders::flushTexMatrix(GLint location,
|
||||
0, -GR_Scalar1, GR_Scalar1,
|
||||
0, 0, GrMatrix::I()[8]
|
||||
);
|
||||
temp.preConcat(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
|
||||
temp.preConcat(fCurrDrawState.fTextureMatrices[0]);
|
||||
m = &temp;
|
||||
} else {
|
||||
GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
|
||||
m = &fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
|
||||
m = &fCurrDrawState.fTextureMatrices[0];
|
||||
}
|
||||
|
||||
// ES doesn't allow you to pass true to the transpose param,
|
||||
@ -644,74 +645,77 @@ void GrGpuGLShaders::flushProgram(PrimitiveType type) {
|
||||
|
||||
Programs nextProgram = kNoTexture_Program;
|
||||
|
||||
if (!VertexHasTexCoords(fGeometrySrc.fVertexLayout)) {
|
||||
GrTexture* texture = fCurrDrawState.fTextures[0];
|
||||
bool posAsTex =
|
||||
StagePosAsTexCoordVertexLayoutBit(0) & fGeometrySrc.fVertexLayout;
|
||||
|
||||
if (!VertexUsesStage(0, fGeometrySrc.fVertexLayout)) {
|
||||
goto HAVE_NEXT_PROGRAM;
|
||||
}
|
||||
|
||||
GrAssert(fCurrDrawState.fTexture);
|
||||
GrAssert(NULL != texture);
|
||||
|
||||
switch (fCurrDrawState.fSamplerState.getSampleMode()) {
|
||||
switch (fCurrDrawState.fSamplerStates[0].getSampleMode()) {
|
||||
case GrSamplerState::kRadial_SampleMode:
|
||||
GrAssert(!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective());
|
||||
if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
|
||||
GrAssert(!fCurrDrawState.fTextureMatrices[0].hasPerspective());
|
||||
GrAssert(GrTexture::kAlpha_8_PixelConfig != texture->config());
|
||||
if (posAsTex) {
|
||||
nextProgram = kRadialTextureVertCoords_Program;
|
||||
} else {
|
||||
nextProgram = kRadialTextureTexCoords_Program;
|
||||
}
|
||||
break;
|
||||
case GrSamplerState::kSweep_SampleMode:
|
||||
GrAssert(!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective());
|
||||
if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
|
||||
GrAssert(!fCurrDrawState.fTextureMatrices[0].hasPerspective());
|
||||
GrAssert(GrTexture::kAlpha_8_PixelConfig != texture->config());
|
||||
if (posAsTex) {
|
||||
nextProgram = kSweepTextureVertCoords_Program;
|
||||
} else {
|
||||
nextProgram = kSweepTextureTexCoords_Program;
|
||||
}
|
||||
break;
|
||||
case GrSamplerState::kRadial2_SampleMode:
|
||||
GrAssert(!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective());
|
||||
if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
|
||||
GrAssert(!fCurrDrawState.fTextureMatrices[0].hasPerspective());
|
||||
GrAssert(GrTexture::kAlpha_8_PixelConfig != texture->config());
|
||||
if (posAsTex) {
|
||||
nextProgram = kTwoPointRadialTextureVertCoords_Program;
|
||||
} else {
|
||||
nextProgram = kTwoPointRadialTextureTexCoords_Program;
|
||||
}
|
||||
break;
|
||||
case GrSamplerState::kAlphaMod_SampleMode:
|
||||
GrAssert(((GrGLTexture*)fCurrDrawState.fTexture)->orientation() ==
|
||||
GrGLTexture::kTopDown_Orientation);
|
||||
(((GrGLTexture*)fCurrDrawState.fTexture)->uploadFormat() == GL_ALPHA);
|
||||
|
||||
nextProgram = kText_Program;
|
||||
break;
|
||||
case GrSamplerState::kNormal_SampleMode: {
|
||||
GR_DEBUGCODE(GrGLTexture* tex = (GrGLTexture*)fCurrDrawState.fTexture;)
|
||||
GrAssert(tex);
|
||||
|
||||
bool persp = fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective();
|
||||
|
||||
if (fGeometrySrc.fVertexLayout & kPositionAsTexCoord_VertexLayoutBit) {
|
||||
nextProgram = persp ? kTextureVertCoordsProj_Program :
|
||||
kTextureVertCoords_Program;
|
||||
case GrSamplerState::kNormal_SampleMode:
|
||||
if (GrTexture::kAlpha_8_PixelConfig == texture->config()) {
|
||||
GrAssert(((GrGLTexture*)texture)->orientation() ==
|
||||
GrGLTexture::kTopDown_Orientation);
|
||||
GrAssert(!posAsTex);
|
||||
nextProgram = kText_Program;
|
||||
} else {
|
||||
nextProgram = persp ? kTextureTexCoordsProj_Program :
|
||||
kTextureTexCoords_Program;
|
||||
}
|
||||
// check for case when frag shader can skip the color modulation
|
||||
if (!persp && !(fGeometrySrc.fVertexLayout
|
||||
& kColor_VertexLayoutBit) &&
|
||||
0xffffffff == fCurrDrawState.fColor) {
|
||||
switch (nextProgram) {
|
||||
case kTextureVertCoords_Program:
|
||||
nextProgram = kTextureVertCoordsNoColor_Program;
|
||||
break;
|
||||
case kTextureTexCoords_Program:
|
||||
nextProgram = kTextureTexCoordsNoColor_Program;
|
||||
break;
|
||||
default:
|
||||
GrAssert("Unexpected");
|
||||
break;
|
||||
bool persp = fCurrDrawState.fTextureMatrices[0].hasPerspective();
|
||||
if (posAsTex) {
|
||||
nextProgram = persp ? kTextureVertCoordsProj_Program :
|
||||
kTextureVertCoords_Program;
|
||||
} else {
|
||||
nextProgram = persp ? kTextureTexCoordsProj_Program :
|
||||
kTextureTexCoords_Program;
|
||||
}
|
||||
// check for case when frag shader can skip the color modulation
|
||||
if (!persp && !(fGeometrySrc.fVertexLayout
|
||||
& kColor_VertexLayoutBit) &&
|
||||
0xffffffff == fCurrDrawState.fColor) {
|
||||
switch (nextProgram) {
|
||||
case kTextureVertCoords_Program:
|
||||
nextProgram = kTextureVertCoordsNoColor_Program;
|
||||
break;
|
||||
case kTextureTexCoords_Program:
|
||||
nextProgram = kTextureTexCoordsNoColor_Program;
|
||||
break;
|
||||
default:
|
||||
GrAssert("Unexpected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
default:
|
||||
GrAssert(!"Unknown samplemode");
|
||||
break;
|
||||
@ -729,20 +733,26 @@ HAVE_NEXT_PROGRAM:
|
||||
|
||||
bool GrGpuGLShaders::flushGraphicsState(PrimitiveType type) {
|
||||
|
||||
for (int s = 1; s < kNumStages; ++s) {
|
||||
if (VertexUsesStage(s, fGeometrySrc.fVertexLayout)) {
|
||||
unimpl("the hard-coded shaders used by this "
|
||||
"class only support 1 stage");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
flushGLStateCommon(type);
|
||||
|
||||
if (fRenderTargetChanged) {
|
||||
// our coords are in pixel space and the GL matrices map to NDC
|
||||
// so if the viewport changed, our matrix is now wrong.
|
||||
#if ATTRIBUTE_MATRIX
|
||||
fHWDrawState.fMatrixModeCache[kModelView_MatrixMode].setScale(GR_ScalarMax,
|
||||
GR_ScalarMax);
|
||||
fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
#else
|
||||
// we assume all shader matrices may be wrong after viewport changes
|
||||
for (int p = 0; p < kProgramCount; ++p) {
|
||||
// set to illegal matrix
|
||||
fPrograms[p].fMatrixModeCache[kModelView_MatrixMode].setScale(GR_ScalarMax,
|
||||
GR_ScalarMax);
|
||||
fPrograms[p].fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
}
|
||||
#endif
|
||||
fRenderTargetChanged = false;
|
||||
@ -783,36 +793,35 @@ bool GrGpuGLShaders::flushGraphicsState(PrimitiveType type) {
|
||||
}
|
||||
|
||||
#if ATTRIBUTE_MATRIX
|
||||
GrMatrix* currentMats = fHWDrawState.fMatrixModeCache;
|
||||
GrMatrix& currentViewMatrix = fHWDrawState.fViewMatrix;
|
||||
GrMatrix& currentTexMatrix = fHWDrawState.fTextureMatrices[0];
|
||||
GrGLTexture::Orientation& orientation = fTextureOrientation;
|
||||
#else
|
||||
GrMatrix* currentMats = fPrograms[fHWProgram].fMatrixModeCache;
|
||||
GrMatrix& currentViewMatrix = fPrograms[fHWProgram].fViewMatrix;
|
||||
GrMatrix& currentTexMatrix = fPrograms[fHWProgram].fTextureMatrices[0];
|
||||
GrGLTexture::Orientation& orientation =
|
||||
fPrograms[fHWProgram].fTextureOrientation;
|
||||
#endif
|
||||
|
||||
if (currentMats[kModelView_MatrixMode] !=
|
||||
fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
|
||||
if (currentViewMatrix !=
|
||||
fCurrDrawState.fViewMatrix) {
|
||||
flushMatrix(fPrograms[fHWProgram].fMatrixLocation);
|
||||
currentMats[kModelView_MatrixMode] =
|
||||
fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
|
||||
currentViewMatrix = fCurrDrawState.fViewMatrix;
|
||||
}
|
||||
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTexture;
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[0];
|
||||
if (NULL != texture) {
|
||||
if (-1 != fPrograms[fHWProgram].fTexMatrixLocation &&
|
||||
(currentMats[kTexture_MatrixMode] !=
|
||||
fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode] ||
|
||||
(currentTexMatrix != fCurrDrawState.fTextureMatrices[0] ||
|
||||
orientation != texture->orientation())) {
|
||||
flushTexMatrix(fPrograms[fHWProgram].fTexMatrixLocation,
|
||||
texture->orientation());
|
||||
currentMats[kTexture_MatrixMode] =
|
||||
fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
|
||||
currentTexMatrix = fCurrDrawState.fTextureMatrices[0];
|
||||
orientation = texture->orientation();
|
||||
}
|
||||
}
|
||||
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerState;
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[0];
|
||||
if (-1 != fPrograms[fHWProgram].fTwoPointParamsLocation &&
|
||||
(fPrograms[fHWProgram].fRadial2CenterX1 != sampler.getRadial2CenterX1() ||
|
||||
fPrograms[fHWProgram].fRadial2Radius0 != sampler.getRadial2Radius0() ||
|
||||
@ -833,15 +842,17 @@ void GrGpuGLShaders::setupGeometry(uint32_t startVertex,
|
||||
uint32_t vertexCount,
|
||||
uint32_t indexCount) {
|
||||
|
||||
int newColorOffset, newTexCoordOffset;
|
||||
int newColorOffset;
|
||||
int newTexCoordOffsets[kNumStages];
|
||||
|
||||
GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
|
||||
&newTexCoordOffset,
|
||||
&newColorOffset);
|
||||
int oldColorOffset, oldTexCoordOffset;
|
||||
GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
|
||||
&oldTexCoordOffset,
|
||||
&oldColorOffset);
|
||||
GLsizei newStride = VertexSizeAndOffsetsByStage(fGeometrySrc.fVertexLayout,
|
||||
newTexCoordOffsets,
|
||||
&newColorOffset);
|
||||
int oldColorOffset;
|
||||
int oldTexCoordOffsets[kNumStages];
|
||||
GLsizei oldStride = VertexSizeAndOffsetsByStage(fHWGeometryState.fVertexLayout,
|
||||
oldTexCoordOffsets,
|
||||
&oldColorOffset);
|
||||
|
||||
const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
|
||||
|
||||
@ -906,16 +917,17 @@ void GrGpuGLShaders::setupGeometry(uint32_t startVertex,
|
||||
fHWGeometryState.fPositionPtr = posPtr;
|
||||
}
|
||||
|
||||
if (newTexCoordOffset > 0) {
|
||||
GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffset;
|
||||
if (oldTexCoordOffset <= 0) {
|
||||
// this class only supports one stage.
|
||||
if (newTexCoordOffsets[0] > 0) {
|
||||
GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[0];
|
||||
if (oldTexCoordOffsets[0] <= 0) {
|
||||
GR_GL(EnableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
|
||||
}
|
||||
if (posChange || newTexCoordOffset != oldTexCoordOffset) {
|
||||
if (posChange || newTexCoordOffsets[0] != oldTexCoordOffsets[0]) {
|
||||
GR_GL(VertexAttribPointer(GR_GL_TEX_ATTR_LOCATION, 2, scalarType,
|
||||
texCoordNorm, newStride, texCoordPtr));
|
||||
}
|
||||
} else if (oldTexCoordOffset > 0) {
|
||||
} else if (oldTexCoordOffsets[0] > 0) {
|
||||
GR_GL(DisableVertexAttribArray(GR_GL_TEX_ATTR_LOCATION));
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,8 @@ private:
|
||||
|
||||
// these reflect the current values of uniforms
|
||||
// (GL uniform values travel with program)
|
||||
GrMatrix fMatrixModeCache[kMatrixModeCount];
|
||||
GrMatrix fViewMatrix;
|
||||
GrMatrix fTextureMatrices[kNumStages];
|
||||
GrColor fColor;
|
||||
GrGLTexture::Orientation fTextureOrientation;
|
||||
GrScalar fRadial2CenterX1;
|
||||
|
@ -41,17 +41,16 @@
|
||||
const char GR_SHADER_PRECISION[] = "";
|
||||
#endif
|
||||
|
||||
|
||||
#define POS_ATTR_LOCATION 0
|
||||
#define TEX_ATTR_LOCATION 1
|
||||
#define COL_ATTR_LOCATION 2
|
||||
#define TEX_ATTR_LOCATION(X) (1 + X)
|
||||
#define COL_ATTR_LOCATION (2 + GrDrawTarget::kMaxTexCoords)
|
||||
#if ATTRIBUTE_MATRIX
|
||||
#define VIEWMAT_ATTR_LOCATION 3
|
||||
#define TEXMAT_ATTR_LOCATION(X) (6 + 3 * (X))
|
||||
#define VIEWMAT_ATTR_LOCATION (3 + GrDrawTarget::kMaxTexCoords)
|
||||
#define TEXMAT_ATTR_LOCATION(X) (6 + GrDrawTarget::kMaxTexCoords + 3 * (X))
|
||||
#define BOGUS_MATRIX_UNI_LOCATION 1000
|
||||
#endif
|
||||
|
||||
const int GrGpuGLShaders2::NUM_STAGES = 1;
|
||||
|
||||
struct GrGpuGLShaders2::StageUniLocations {
|
||||
GLint fTextureMatrixUni;
|
||||
GLint fSamplerUni;
|
||||
@ -60,7 +59,7 @@ struct GrGpuGLShaders2::StageUniLocations {
|
||||
|
||||
struct GrGpuGLShaders2::UniLocations {
|
||||
GLint fViewMatrixUni;
|
||||
StageUniLocations fStages[NUM_STAGES];
|
||||
StageUniLocations fStages[kNumStages];
|
||||
};
|
||||
|
||||
// Records per-program information
|
||||
@ -82,11 +81,11 @@ struct GrGpuGLShaders2::Program {
|
||||
// these reflect the current values of uniforms
|
||||
// (GL uniform values travel with program)
|
||||
GrMatrix fViewMatrix;
|
||||
GrMatrix fTextureMatrix[NUM_STAGES];
|
||||
GrGLTexture::Orientation fTextureOrientation[NUM_STAGES];
|
||||
GrScalar fRadial2CenterX1[NUM_STAGES];
|
||||
GrScalar fRadial2Radius0[NUM_STAGES];
|
||||
bool fRadial2PosRoot[NUM_STAGES];
|
||||
GrMatrix fTextureMatrix[kNumStages];
|
||||
GrGLTexture::Orientation fTextureOrientation[kNumStages];
|
||||
GrScalar fRadial2CenterX1[kNumStages];
|
||||
GrScalar fRadial2Radius0[kNumStages];
|
||||
bool fRadial2PosRoot[kNumStages];
|
||||
|
||||
};
|
||||
|
||||
@ -127,12 +126,12 @@ struct GrGpuGLShaders2::ProgramDesc {
|
||||
// for this to pack
|
||||
unsigned short fOptFlags : 16;
|
||||
|
||||
StageDesc fStages[NUM_STAGES];
|
||||
StageDesc fStages[kNumStages];
|
||||
|
||||
bool operator == (const ProgramDesc& desc) const {
|
||||
// keep 4-byte aligned and tightly packed
|
||||
GR_STATIC_ASSERT(4 == sizeof(StageDesc));
|
||||
GR_STATIC_ASSERT(2 + 2 + 4 * NUM_STAGES == sizeof(ProgramDesc));
|
||||
GR_STATIC_ASSERT(2 + 2 + 4 * kNumStages == sizeof(ProgramDesc));
|
||||
return 0 == memcmp(this, &desc, sizeof(ProgramDesc));
|
||||
}
|
||||
};
|
||||
@ -237,7 +236,6 @@ static uint32_t ror(uint32_t x) {
|
||||
return (x >> 8) | (x << 24);
|
||||
}
|
||||
|
||||
|
||||
GrGpuGLShaders2::ProgramCache::HashKey::HashKey(const ProgramDesc& desc) {
|
||||
fDesc = desc;
|
||||
// if you change the size of the desc, need to update the hash function
|
||||
@ -289,7 +287,11 @@ typedef GrSStringBuilder<16> GrTokenString;
|
||||
|
||||
#define POS_ATTR_NAME "aPosition"
|
||||
#define COL_ATTR_NAME "aColor"
|
||||
#define TEX_ATTR_NAME "aTexture"
|
||||
|
||||
static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
|
||||
*s = "aTexCoord";
|
||||
s->appendInt(coordIdx);
|
||||
}
|
||||
|
||||
static inline const char* float_vector_type(int count) {
|
||||
static const char* FLOAT_VECS[] = {"ERROR", "float", "vec2", "vec3", "vec4"};
|
||||
@ -347,14 +349,6 @@ static void radial2_varying_name(int stage, GrStringBuilder* s) {
|
||||
#include "GrRandom.h"
|
||||
|
||||
void GrGpuGLShaders2::ProgramUnitTest() {
|
||||
static const uint16_t VFORMATS[] = {
|
||||
0,
|
||||
kSeparateTexCoord_VertexLayoutBit,
|
||||
kPositionAsTexCoord_VertexLayoutBit,
|
||||
kSeparateTexCoord_VertexLayoutBit | kColor_VertexLayoutBit,
|
||||
kPositionAsTexCoord_VertexLayoutBit | kColor_VertexLayoutBit,
|
||||
kTextFormat_VertexLayoutBit
|
||||
};
|
||||
static const int PROG_OPTS[] = {
|
||||
0,
|
||||
ProgramDesc::kNotPoints_OptFlagBit,
|
||||
@ -379,19 +373,35 @@ void GrGpuGLShaders2::ProgramUnitTest() {
|
||||
ProgramDesc pdesc;
|
||||
memset(&pdesc, 0, sizeof(pdesc));
|
||||
|
||||
static const int NUM_TESTS = 1024;
|
||||
static const int NUM_TESTS = 512;
|
||||
|
||||
// GrRandoms nextU() values have patterns in the low bits
|
||||
// So using nextU() % array_count might never take some values.
|
||||
GrRandom random;
|
||||
for (int t = 0; t < NUM_TESTS; ++t) {
|
||||
int x = (int)(random.nextF() * GR_ARRAY_COUNT(VFORMATS));
|
||||
pdesc.fVertexLayout = VFORMATS[x];
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(PROG_OPTS));
|
||||
|
||||
pdesc.fVertexLayout = 0;
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
// enable the stage?
|
||||
if (random.nextF() > .5f) {
|
||||
// use separate tex coords?
|
||||
if (random.nextF() > .5f) {
|
||||
int t = (int)(random.nextF() * kMaxTexCoords);
|
||||
pdesc.fVertexLayout |= StageTexCoordVertexLayoutBit(s, t);
|
||||
} else {
|
||||
pdesc.fVertexLayout |= StagePosAsTexCoordVertexLayoutBit(s);
|
||||
}
|
||||
}
|
||||
// use text-formatted verts?
|
||||
if (random.nextF() > .5f) {
|
||||
pdesc.fVertexLayout |= kTextFormat_VertexLayoutBit;
|
||||
}
|
||||
}
|
||||
|
||||
int x = (int)(random.nextF() * GR_ARRAY_COUNT(PROG_OPTS));
|
||||
pdesc.fOptFlags = PROG_OPTS[x];
|
||||
for (int s = 0; s < NUM_STAGES; ++s) {
|
||||
x = (int)(random.nextF() * 2.f);
|
||||
pdesc.fStages[s].fEnabled = x;
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
pdesc.fStages[s].fEnabled = VertexUsesStage(s, pdesc.fVertexLayout);
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_OPTS));
|
||||
pdesc.fStages[s].fOptFlags = STAGE_OPTS[x];
|
||||
x = (int)(random.nextF() * GR_ARRAY_COUNT(STAGE_MODULATES));
|
||||
@ -696,30 +706,46 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
}
|
||||
segments.fFSCode = "void main() {\n";
|
||||
|
||||
bool textureCoordAttr = false;
|
||||
static const char* IN_COORDS[] = {POS_ATTR_NAME, TEX_ATTR_NAME};
|
||||
const char* inCoords = NULL;
|
||||
if ((kSeparateTexCoord_VertexLayoutBit | kTextFormat_VertexLayoutBit) &
|
||||
layout) {
|
||||
segments.fVSAttrs += "attribute vec2 " TEX_ATTR_NAME ";\n";
|
||||
inCoords = IN_COORDS[1];
|
||||
textureCoordAttr = true;
|
||||
} else if (kPositionAsTexCoord_VertexLayoutBit & layout) {
|
||||
inCoords = IN_COORDS[0];
|
||||
// add texture coordinates that are used to the list of vertex attr decls
|
||||
GrTokenString texCoordAttrs[kMaxTexCoords];
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
if (VertexUsesTexCoordIdx(t, layout)) {
|
||||
tex_attr_name(t, texCoordAttrs + t);
|
||||
|
||||
segments.fVSAttrs += "attribute vec2 ";
|
||||
segments.fVSAttrs += texCoordAttrs[t];
|
||||
segments.fVSAttrs += ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
GrTokenString inColor = "vColor";
|
||||
GR_STATIC_ASSERT(NUM_STAGES <= 9);
|
||||
// for each enabled stage figure out what the input coordinates are
|
||||
// and count the number of stages in use.
|
||||
const char* stageInCoords[kNumStages];
|
||||
int numActiveStages = 0;
|
||||
for (int i = 0; i < NUM_STAGES; ++i) {
|
||||
if (desc.fStages[i].fEnabled) {
|
||||
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (desc.fStages[s].fEnabled) {
|
||||
if (StagePosAsTexCoordVertexLayoutBit(s) & layout) {
|
||||
stageInCoords[s] = POS_ATTR_NAME;
|
||||
} else {
|
||||
int tcIdx = VertexTexCoordsForStage(s, layout);
|
||||
// we better have input tex coordinates if stage is enabled.
|
||||
GrAssert(tcIdx >= 0);
|
||||
GrAssert(texCoordAttrs[tcIdx].length());
|
||||
stageInCoords[s] = texCoordAttrs[tcIdx].cstr();
|
||||
}
|
||||
++numActiveStages;
|
||||
}
|
||||
}
|
||||
if (NULL != inCoords && numActiveStages) {
|
||||
|
||||
GrTokenString inColor = "vColor";
|
||||
|
||||
// if we have active stages string them together, feeding the output color
|
||||
// of each to the next and generating code for each stage.
|
||||
if (numActiveStages) {
|
||||
int currActiveStage = 0;
|
||||
for (int i = 0; i < NUM_STAGES; ++i) {
|
||||
if (desc.fStages[i].fEnabled) {
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (desc.fStages[s].fEnabled) {
|
||||
GrTokenString outColor;
|
||||
if (currActiveStage < (numActiveStages - 1)) {
|
||||
outColor = "color";
|
||||
@ -730,13 +756,13 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
} else {
|
||||
outColor = "gl_FragColor";
|
||||
}
|
||||
GenStageCode(i,
|
||||
desc.fStages[i],
|
||||
GenStageCode(s,
|
||||
desc.fStages[s],
|
||||
haveColor ? inColor.cstr() : NULL,
|
||||
outColor.cstr(),
|
||||
inCoords,
|
||||
stageInCoords[s],
|
||||
&segments,
|
||||
&program->fUniLocations.fStages[i]);
|
||||
&program->fUniLocations.fStages[s]);
|
||||
++currActiveStage;
|
||||
inColor = outColor;
|
||||
haveColor = true;
|
||||
@ -835,8 +861,12 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
|
||||
// Bind the attrib locations to same values for all shaders
|
||||
GR_GL(BindAttribLocation(progID, POS_ATTR_LOCATION, POS_ATTR_NAME));
|
||||
if (textureCoordAttr) {
|
||||
GR_GL(BindAttribLocation(progID, TEX_ATTR_LOCATION, TEX_ATTR_NAME));
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
if (texCoordAttrs[t].length()) {
|
||||
GR_GL(BindAttribLocation(progID,
|
||||
TEX_ATTR_LOCATION(t),
|
||||
texCoordAttrs[t].cstr()));
|
||||
}
|
||||
}
|
||||
|
||||
#if ATTRIBUTE_MATRIX
|
||||
@ -848,12 +878,12 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
|
||||
program->fUniLocations.fViewMatrixUni = BOGUS_MATRIX_UNI_LOCATION;
|
||||
|
||||
for (int i = 0; i < NUM_STAGES; ++i) {
|
||||
if (desc.fStages[i].fEnabled) {
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (desc.fStages[s].fEnabled) {
|
||||
GR_GL(BindAttribLocation(progID,
|
||||
TEXMAT_ATTR_LOCATION(i),
|
||||
TEXMAT_ATTR_LOCATION(s),
|
||||
tex_matrix_name(i).cstr()));
|
||||
program->fUniLocations.fStages[i].fTextureMatrixUni =
|
||||
program->fUniLocations.fStages[s].fTextureMatrixUni =
|
||||
BOGUS_MATRIX_UNI_LOCATION;
|
||||
}
|
||||
}
|
||||
@ -888,13 +918,13 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
GR_GL(GetUniformLocation(progID, VIEW_MATRIX_NAME));
|
||||
GrAssert(-1 != program->fUniLocations.fViewMatrixUni);
|
||||
#endif
|
||||
for (int i = 0; i < NUM_STAGES; ++i) {
|
||||
StageUniLocations& locations = program->fUniLocations.fStages[i];
|
||||
if (desc.fStages[i].fEnabled) {
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
StageUniLocations& locations = program->fUniLocations.fStages[s];
|
||||
if (desc.fStages[s].fEnabled) {
|
||||
#if !ATTRIBUTE_MATRIX
|
||||
if (locations.fTextureMatrixUni) {
|
||||
GrTokenString texMName;
|
||||
tex_matrix_name(i, &texMName);
|
||||
tex_matrix_name(s, &texMName);
|
||||
locations.fTextureMatrixUni = GR_GL(GetUniformLocation(
|
||||
progID,
|
||||
texMName.cstr()));
|
||||
@ -907,7 +937,7 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
|
||||
if (locations.fSamplerUni) {
|
||||
GrTokenString samplerName;
|
||||
sampler_name(i, &samplerName);
|
||||
sampler_name(s, &samplerName);
|
||||
locations.fSamplerUni = GR_GL(GetUniformLocation(
|
||||
progID,
|
||||
samplerName.cstr()));
|
||||
@ -918,7 +948,7 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
|
||||
if (locations.fRadial2Uni) {
|
||||
GrTokenString radial2ParamName;
|
||||
radial2_param_name(i, &radial2ParamName);
|
||||
radial2_param_name(s, &radial2ParamName);
|
||||
locations.fRadial2Uni = GR_GL(GetUniformLocation(
|
||||
progID,
|
||||
radial2ParamName.cstr()));
|
||||
@ -935,13 +965,13 @@ void GrGpuGLShaders2::GenProgram(const ProgramDesc& desc,
|
||||
GR_GL(UseProgram(progID));
|
||||
|
||||
// init sampler unis and set bogus values for state tracking
|
||||
for (int i = 0; i < NUM_STAGES; ++i) {
|
||||
if (-1 != program->fUniLocations.fStages[i].fSamplerUni) {
|
||||
GR_GL(Uniform1i(program->fUniLocations.fStages[i].fSamplerUni, i));
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (-1 != program->fUniLocations.fStages[s].fSamplerUni) {
|
||||
GR_GL(Uniform1i(program->fUniLocations.fStages[s].fSamplerUni, s));
|
||||
}
|
||||
program->fTextureMatrix[i].setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
program->fRadial2CenterX1[i] = GR_ScalarMax;
|
||||
program->fRadial2Radius0[i] = -GR_ScalarMax;
|
||||
program->fTextureMatrix[s].setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
program->fRadial2CenterX1[s] = GR_ScalarMax;
|
||||
program->fRadial2Radius0[s] = -GR_ScalarMax;
|
||||
}
|
||||
program->fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
}
|
||||
@ -950,70 +980,63 @@ void GrGpuGLShaders2::getProgramDesc(PrimitiveType primType, ProgramDesc* desc)
|
||||
|
||||
// Must initialize all fields or cache will have false negatives!
|
||||
desc->fVertexLayout = fGeometrySrc.fVertexLayout;
|
||||
desc->fStages[0].fEnabled = VertexHasTexCoords(fGeometrySrc.fVertexLayout);
|
||||
for (int i = 1; i < NUM_STAGES; ++i) {
|
||||
desc->fStages[i].fEnabled = false;
|
||||
desc->fStages[i].fOptFlags = 0;
|
||||
desc->fStages[i].fCoordMapping = (StageDesc::CoordMapping)0;
|
||||
desc->fStages[i].fModulation = (StageDesc::Modulation)0;
|
||||
}
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
StageDesc& stage = desc->fStages[s];
|
||||
|
||||
if (primType != kPoints_PrimitiveType) {
|
||||
desc->fOptFlags = ProgramDesc::kNotPoints_OptFlagBit;
|
||||
} else {
|
||||
desc->fOptFlags = 0;
|
||||
}
|
||||
#if SKIP_COLOR_MODULATE_OPT
|
||||
if (!(desc->fVertexLayout & kColor_VertexLayoutBit) &&
|
||||
(0xffffffff == fCurrDrawState.fColor)) {
|
||||
desc->fOptFlags |= ProgramDesc::kVertexColorAllOnes_OptFlagBit;
|
||||
}
|
||||
#endif
|
||||
stage.fEnabled = VertexUsesStage(s, fGeometrySrc.fVertexLayout);
|
||||
|
||||
StageDesc& stage = desc->fStages[0];
|
||||
|
||||
if (stage.fEnabled) {
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTexture;
|
||||
GrAssert(NULL != texture);
|
||||
// we matrix to invert when orientation is TopDown, so make sure
|
||||
// we aren't in that case before flagging as identity.
|
||||
if (fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].isIdentity() &&
|
||||
GrGLTexture::kTopDown_Orientation == texture->orientation()) {
|
||||
stage.fOptFlags = StageDesc::kIdentityMatrix_OptFlagBit;
|
||||
} else if (!fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode].hasPerspective()) {
|
||||
stage.fOptFlags = StageDesc::kNoPerspective_OptFlagBit;
|
||||
if (primType != kPoints_PrimitiveType) {
|
||||
desc->fOptFlags = ProgramDesc::kNotPoints_OptFlagBit;
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
desc->fOptFlags = 0;
|
||||
}
|
||||
switch (fCurrDrawState.fSamplerState.getSampleMode()) {
|
||||
case GrSamplerState::kNormal_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
|
||||
stage.fModulation = StageDesc::kColor_Modulation;
|
||||
break;
|
||||
case GrSamplerState::kAlphaMod_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
|
||||
stage.fModulation = StageDesc::kAlpha_Modulation;
|
||||
break;
|
||||
case GrSamplerState::kRadial_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
|
||||
stage.fModulation = StageDesc::kColor_Modulation;
|
||||
break;
|
||||
case GrSamplerState::kRadial2_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kRadial2Gradient_CoordMapping;
|
||||
stage.fModulation = StageDesc::kColor_Modulation;
|
||||
break;
|
||||
case GrSamplerState::kSweep_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
|
||||
stage.fModulation = StageDesc::kColor_Modulation;
|
||||
break;
|
||||
default:
|
||||
GrAssert(!"Unexpected sample mode!");
|
||||
break;
|
||||
#if SKIP_COLOR_MODULATE_OPT
|
||||
if (!(desc->fVertexLayout & kColor_VertexLayoutBit) &&
|
||||
(0xffffffff == fCurrDrawState.fColor)) {
|
||||
desc->fOptFlags |= ProgramDesc::kVertexColorAllOnes_OptFlagBit;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stage.fEnabled) {
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
|
||||
GrAssert(NULL != texture);
|
||||
// we matrix to invert when orientation is TopDown, so make sure
|
||||
// we aren't in that case before flagging as identity.
|
||||
if (fCurrDrawState.fTextureMatrices[s].isIdentity() &&
|
||||
GrGLTexture::kTopDown_Orientation == texture->orientation()) {
|
||||
stage.fOptFlags = StageDesc::kIdentityMatrix_OptFlagBit;
|
||||
} else if (!fCurrDrawState.fTextureMatrices[s].hasPerspective()) {
|
||||
stage.fOptFlags = StageDesc::kNoPerspective_OptFlagBit;
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
}
|
||||
switch (fCurrDrawState.fSamplerStates[s].getSampleMode()) {
|
||||
case GrSamplerState::kNormal_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kIdentity_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kRadial_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kRadialGradient_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kRadial2_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kRadial2Gradient_CoordMapping;
|
||||
break;
|
||||
case GrSamplerState::kSweep_SampleMode:
|
||||
stage.fCoordMapping = StageDesc::kSweepGradient_CoordMapping;
|
||||
break;
|
||||
default:
|
||||
GrAssert(!"Unexpected sample mode!");
|
||||
break;
|
||||
}
|
||||
if (GrTexture::kAlpha_8_PixelConfig == texture->config()) {
|
||||
stage.fModulation = StageDesc::kAlpha_Modulation;
|
||||
} else {
|
||||
stage.fModulation = StageDesc::kColor_Modulation;
|
||||
}
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
stage.fCoordMapping = (StageDesc::CoordMapping)0;
|
||||
stage.fModulation = (StageDesc::Modulation)0;
|
||||
}
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
stage.fCoordMapping = (StageDesc::CoordMapping)0;
|
||||
stage.fModulation = (StageDesc::Modulation)0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1088,7 +1111,9 @@ void GrGpuGLShaders2::resetContextHelper() {
|
||||
fHWGeometryState.fVertexLayout = 0;
|
||||
fHWGeometryState.fPositionPtr = (void*) ~0;
|
||||
GR_GL(DisableVertexAttribArray(COL_ATTR_LOCATION));
|
||||
GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION));
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
|
||||
}
|
||||
GR_GL(EnableVertexAttribArray(POS_ATTR_LOCATION));
|
||||
|
||||
fHWProgramID = 0;
|
||||
@ -1100,7 +1125,7 @@ void GrGpuGLShaders2::flushViewMatrix() {
|
||||
GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
|
||||
0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
|
||||
0, 0, GrMatrix::I()[8]);
|
||||
m.setConcat(m, fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]);
|
||||
m.setConcat(m, fCurrDrawState.fViewMatrix);
|
||||
|
||||
// ES doesn't allow you to pass true to the transpose param,
|
||||
// so do our own transpose
|
||||
@ -1124,11 +1149,11 @@ void GrGpuGLShaders2::flushViewMatrix() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void GrGpuGLShaders2::flushTextureMatrix() {
|
||||
void GrGpuGLShaders2::flushTextureMatrix(int stage) {
|
||||
|
||||
GrAssert(NULL != fCurrDrawState.fTexture);
|
||||
GrAssert(NULL != fCurrDrawState.fTextures[stage]);
|
||||
GrGLTexture::Orientation orientation =
|
||||
((GrGLTexture*)fCurrDrawState.fTexture)->orientation();
|
||||
((GrGLTexture*)fCurrDrawState.fTextures[stage])->orientation();
|
||||
|
||||
GrMatrix* m;
|
||||
GrMatrix temp;
|
||||
@ -1138,11 +1163,11 @@ void GrGpuGLShaders2::flushTextureMatrix() {
|
||||
0, -GR_Scalar1, GR_Scalar1,
|
||||
0, 0, GrMatrix::I()[8]
|
||||
);
|
||||
temp.preConcat(fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode]);
|
||||
temp.preConcat(fCurrDrawState.fTextureMatrices[stage]);
|
||||
m = &temp;
|
||||
} else {
|
||||
GrAssert(GrGLTexture::kTopDown_Orientation == orientation);
|
||||
m = &fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
|
||||
m = &fCurrDrawState.fTextureMatrices[stage];
|
||||
}
|
||||
|
||||
// ES doesn't allow you to pass true to the transpose param,
|
||||
@ -1163,16 +1188,16 @@ void GrGpuGLShaders2::flushTextureMatrix() {
|
||||
glVertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+1, mt+3);
|
||||
glVertexAttrib4fv(TEXMAT_ATTR_LOCATION(0)+2, mt+6);
|
||||
#else
|
||||
GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fStages[0].fTextureMatrixUni,
|
||||
GR_GL(UniformMatrix3fv(fProgram->fUniLocations.fStages[stage].fTextureMatrixUni,
|
||||
1,
|
||||
false,
|
||||
mt));
|
||||
#endif
|
||||
}
|
||||
|
||||
void GrGpuGLShaders2::flushRadial2() {
|
||||
void GrGpuGLShaders2::flushRadial2(int stage) {
|
||||
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerState;
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[stage];
|
||||
|
||||
GrScalar centerX1 = sampler.getRadial2CenterX1();
|
||||
GrScalar radius0 = sampler.getRadial2Radius0();
|
||||
@ -1187,7 +1212,9 @@ void GrGpuGLShaders2::flushRadial2() {
|
||||
GrScalarToFloat(GrMul(radius0, radius0)),
|
||||
sampler.isRadial2PosRoot() ? 1.f : -1.f
|
||||
};
|
||||
GR_GL(Uniform1fv(fProgram->fUniLocations.fStages[0].fRadial2Uni, 6, unis));
|
||||
GR_GL(Uniform1fv(fProgram->fUniLocations.fStages[stage].fRadial2Uni,
|
||||
6,
|
||||
unis));
|
||||
}
|
||||
|
||||
void GrGpuGLShaders2::flushProgram(PrimitiveType type) {
|
||||
@ -1212,8 +1239,7 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) {
|
||||
// our coords are in pixel space and the GL matrices map to NDC
|
||||
// so if the viewport changed, our matrix is now wrong.
|
||||
#if ATTRIBUTE_MATRIX
|
||||
fHWDrawState.fMatrixModeCache[kModelView_MatrixMode].setScale(GR_ScalarMax,
|
||||
GR_ScalarMax);
|
||||
fHWDrawState.fViewMatrix.setScale(GR_ScalarMax, GR_ScalarMax);
|
||||
#else
|
||||
// we assume all shader matrices may be wrong after viewport changes
|
||||
fProgramCache->invalidateViewMatrices();
|
||||
@ -1241,7 +1267,7 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) {
|
||||
}
|
||||
|
||||
#if ATTRIBUTE_MATRIX
|
||||
GrMatrix& currViewMatrix = fHWDrawState.fMatrixModeCache[kModelView_MatrixMode];
|
||||
GrMatrix& currViewMatrix = fHWDrawState.fViewMatrix;
|
||||
GrMatrix& currTextureMatrix = fHWDrawState.fMatrixModeCache[kTexture_MatrixMode];
|
||||
GrGLTexture::Orientation& orientation = fTextureOrientation;
|
||||
#else
|
||||
@ -1250,53 +1276,56 @@ bool GrGpuGLShaders2::flushGraphicsState(PrimitiveType type) {
|
||||
GrGLTexture::Orientation& orientation = fProgram->fTextureOrientation[0];
|
||||
#endif
|
||||
|
||||
if (currViewMatrix != fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode]) {
|
||||
if (currViewMatrix != fCurrDrawState.fViewMatrix) {
|
||||
flushViewMatrix();
|
||||
currViewMatrix = fCurrDrawState.fMatrixModeCache[kModelView_MatrixMode];
|
||||
currViewMatrix = fCurrDrawState.fViewMatrix;
|
||||
}
|
||||
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTexture;
|
||||
if (NULL != texture) {
|
||||
if (-1 != fProgram->fUniLocations.fStages[0].fTextureMatrixUni &&
|
||||
(currTextureMatrix !=
|
||||
fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode] ||
|
||||
orientation != texture->orientation())) {
|
||||
flushTextureMatrix();
|
||||
currTextureMatrix = fCurrDrawState.fMatrixModeCache[kTexture_MatrixMode];
|
||||
orientation = texture->orientation();
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
|
||||
if (NULL != texture) {
|
||||
if (-1 != fProgram->fUniLocations.fStages[s].fTextureMatrixUni &&
|
||||
(currTextureMatrix != fCurrDrawState.fTextureMatrices[s] ||
|
||||
orientation != texture->orientation())) {
|
||||
flushTextureMatrix(s);
|
||||
currTextureMatrix = fCurrDrawState.fTextureMatrices[s];
|
||||
orientation = texture->orientation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerState;
|
||||
if (-1 != fProgram->fUniLocations.fStages[0].fRadial2Uni &&
|
||||
(fProgram->fRadial2CenterX1[0] != sampler.getRadial2CenterX1() ||
|
||||
fProgram->fRadial2Radius0[0] != sampler.getRadial2Radius0() ||
|
||||
fProgram->fRadial2PosRoot[0] != sampler.isRadial2PosRoot())) {
|
||||
const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
|
||||
if (-1 != fProgram->fUniLocations.fStages[s].fRadial2Uni &&
|
||||
(fProgram->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
|
||||
fProgram->fRadial2Radius0[s] != sampler.getRadial2Radius0() ||
|
||||
fProgram->fRadial2PosRoot[s] != sampler.isRadial2PosRoot())) {
|
||||
|
||||
flushRadial2();
|
||||
flushRadial2(s);
|
||||
|
||||
fProgram->fRadial2CenterX1[0] = sampler.getRadial2CenterX1();
|
||||
fProgram->fRadial2Radius0[0] = sampler.getRadial2Radius0();
|
||||
fProgram->fRadial2PosRoot[0] = sampler.isRadial2PosRoot();
|
||||
fProgram->fRadial2CenterX1[s] = sampler.getRadial2CenterX1();
|
||||
fProgram->fRadial2Radius0[s] = sampler.getRadial2Radius0();
|
||||
fProgram->fRadial2PosRoot[s] = sampler.isRadial2PosRoot();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
|
||||
uint32_t startIndex,
|
||||
uint32_t vertexCount,
|
||||
uint32_t indexCount) {
|
||||
uint32_t startIndex,
|
||||
uint32_t vertexCount,
|
||||
uint32_t indexCount) {
|
||||
|
||||
int newColorOffset, newTexCoordOffset;
|
||||
int newColorOffset;
|
||||
int newTexCoordOffsets[kMaxTexCoords];
|
||||
|
||||
GLsizei newStride = VertexSizeAndOffsets(fGeometrySrc.fVertexLayout,
|
||||
&newTexCoordOffset,
|
||||
&newColorOffset);
|
||||
int oldColorOffset, oldTexCoordOffset;
|
||||
GLsizei oldStride = VertexSizeAndOffsets(fHWGeometryState.fVertexLayout,
|
||||
&oldTexCoordOffset,
|
||||
&oldColorOffset);
|
||||
GLsizei newStride = VertexSizeAndOffsetsByIdx(fGeometrySrc.fVertexLayout,
|
||||
newTexCoordOffsets,
|
||||
&newColorOffset);
|
||||
int oldColorOffset;
|
||||
int oldTexCoordOffsets[kMaxTexCoords];
|
||||
GLsizei oldStride = VertexSizeAndOffsetsByIdx(fHWGeometryState.fVertexLayout,
|
||||
oldTexCoordOffsets,
|
||||
&oldColorOffset);
|
||||
|
||||
const GLvoid* posPtr = (GLvoid*)(newStride * startVertex);
|
||||
|
||||
@ -1305,7 +1334,7 @@ void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
|
||||
GrAssert(!fGeometrySrc.fVertexBuffer->isLocked());
|
||||
if (fHWGeometryState.fVertexBuffer != fGeometrySrc.fVertexBuffer) {
|
||||
GrGLVertexBuffer* buf =
|
||||
(GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
|
||||
(GrGLVertexBuffer*)fGeometrySrc.fVertexBuffer;
|
||||
GR_GL(BindBuffer(GL_ARRAY_BUFFER, buf->bufferID()));
|
||||
fHWGeometryState.fVertexBuffer = fGeometrySrc.fVertexBuffer;
|
||||
}
|
||||
@ -1327,8 +1356,7 @@ void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
|
||||
GrAssert(NULL != fGeometrySrc.fIndexBuffer);
|
||||
GrAssert(!fGeometrySrc.fIndexBuffer->isLocked());
|
||||
if (fHWGeometryState.fIndexBuffer != fGeometrySrc.fIndexBuffer) {
|
||||
GrGLIndexBuffer* buf =
|
||||
(GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
|
||||
GrGLIndexBuffer* buf = (GrGLIndexBuffer*)fGeometrySrc.fIndexBuffer;
|
||||
GR_GL(BindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf->bufferID()));
|
||||
fHWGeometryState.fIndexBuffer = fGeometrySrc.fIndexBuffer;
|
||||
}
|
||||
@ -1361,17 +1389,19 @@ void GrGpuGLShaders2::setupGeometry(uint32_t startVertex,
|
||||
fHWGeometryState.fPositionPtr = posPtr;
|
||||
}
|
||||
|
||||
if (newTexCoordOffset > 0) {
|
||||
GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffset;
|
||||
if (oldTexCoordOffset <= 0) {
|
||||
GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION));
|
||||
for (int t = 0; t < kMaxTexCoords; ++t) {
|
||||
if (newTexCoordOffsets[t] > 0) {
|
||||
GLvoid* texCoordPtr = (int8_t*)posPtr + newTexCoordOffsets[t];
|
||||
if (oldTexCoordOffsets[t] <= 0) {
|
||||
GR_GL(EnableVertexAttribArray(TEX_ATTR_LOCATION(t)));
|
||||
}
|
||||
if (posChange || newTexCoordOffsets[t] != oldTexCoordOffsets[t]) {
|
||||
GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION(t), 2, scalarType,
|
||||
texCoordNorm, newStride, texCoordPtr));
|
||||
}
|
||||
} else if (oldTexCoordOffsets[t] > 0) {
|
||||
GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION(t)));
|
||||
}
|
||||
if (posChange || newTexCoordOffset != oldTexCoordOffset) {
|
||||
GR_GL(VertexAttribPointer(TEX_ATTR_LOCATION, 2, scalarType,
|
||||
texCoordNorm, newStride, texCoordPtr));
|
||||
}
|
||||
} else if (oldTexCoordOffset > 0) {
|
||||
GR_GL(DisableVertexAttribArray(TEX_ATTR_LOCATION));
|
||||
}
|
||||
|
||||
if (newColorOffset > 0) {
|
||||
|
@ -37,17 +37,17 @@ protected:
|
||||
uint32_t indexCount);
|
||||
|
||||
private:
|
||||
static const int NUM_STAGES;
|
||||
|
||||
void resetContextHelper();
|
||||
|
||||
// sets the texture matrix uniform for currently bound program
|
||||
void flushTextureMatrix();
|
||||
void flushTextureMatrix(int stage);
|
||||
|
||||
// sets the MVP matrix uniform for currently bound program
|
||||
void flushViewMatrix();
|
||||
|
||||
// flushes the parameters to two point radial gradient
|
||||
void flushRadial2();
|
||||
void flushRadial2(int stage);
|
||||
|
||||
// called at flush time to setup the appropriate program
|
||||
void flushProgram(PrimitiveType type);
|
||||
|
@ -156,9 +156,11 @@ void GrInOrderDrawBuffer::reset() {
|
||||
GrAssert(!fReservedGeometry.fLocked);
|
||||
uint32_t numStates = fStates.count();
|
||||
for (uint32_t i = 0; i < numStates; ++i) {
|
||||
GrTexture* tex = accessSavedDrawState(fStates[i]).fTexture;
|
||||
if (NULL != tex) {
|
||||
tex->unref();
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrTexture* tex = accessSavedDrawState(fStates[i]).fTextures[s];
|
||||
if (NULL != tex) {
|
||||
tex->unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
fDraws.reset();
|
||||
@ -320,8 +322,10 @@ bool GrInOrderDrawBuffer::grabState() {
|
||||
newState = old != fCurrDrawState;
|
||||
}
|
||||
if (newState) {
|
||||
if (NULL != fCurrDrawState.fTexture) {
|
||||
fCurrDrawState.fTexture->ref();
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
if (NULL != fCurrDrawState.fTextures[s]) {
|
||||
fCurrDrawState.fTextures[s]->ref();
|
||||
}
|
||||
}
|
||||
saveCurrentDrawState(&fStates.push_back());
|
||||
}
|
||||
|
@ -23,7 +23,9 @@
|
||||
#include "GrTextStrike_impl.h"
|
||||
#include "GrFontScaler.h"
|
||||
|
||||
static const GrVertexLayout VLAYOUT = GrDrawTarget::kTextFormat_VertexLayoutBit;
|
||||
static const GrVertexLayout VLAYOUT =
|
||||
GrDrawTarget::kTextFormat_VertexLayoutBit |
|
||||
GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
|
||||
|
||||
void GrTextContext::flushGlyphs() {
|
||||
if (fCurrVertex > 0) {
|
||||
@ -33,15 +35,14 @@ void GrTextContext::flushGlyphs() {
|
||||
|
||||
GrSamplerState sampler(GrSamplerState::kRepeat_WrapMode,
|
||||
GrSamplerState::kRepeat_WrapMode,
|
||||
GrSamplerState::kAlphaMod_SampleMode,
|
||||
!fExtMatrix.isIdentity());
|
||||
fDrawTarget->setSamplerState(sampler);
|
||||
fDrawTarget->setSamplerState(0, sampler);
|
||||
|
||||
GrAssert(GrIsALIGN4(fCurrVertex));
|
||||
int nIndices = fCurrVertex + (fCurrVertex >> 1);
|
||||
GrAssert(fCurrTexture);
|
||||
fDrawTarget->setTexture(fCurrTexture);
|
||||
fDrawTarget->setTextureMatrix(GrMatrix::I());
|
||||
fDrawTarget->setTexture(0, fCurrTexture);
|
||||
fDrawTarget->setTextureMatrix(0, GrMatrix::I());
|
||||
fDrawTarget->setIndexSourceToBuffer(fContext->quadIndexBuffer());
|
||||
|
||||
fDrawTarget->drawIndexed(GrDrawTarget::kTriangles_PrimitiveType,
|
||||
|
@ -82,7 +82,7 @@ GrTexture* SkGpuDevice::SkAutoCachedTexture::set(SkGpuDevice* device,
|
||||
if (texture) {
|
||||
// return the native texture
|
||||
fTex = NULL;
|
||||
device->context()->setTexture(texture);
|
||||
device->context()->setTexture(0, texture);
|
||||
} else {
|
||||
// look it up in our cache
|
||||
fTex = device->lockCachedTexture(bitmap, sampler, &texture, false);
|
||||
@ -333,7 +333,7 @@ void SkGpuDevice::gainFocus(SkCanvas* canvas, const SkMatrix& matrix,
|
||||
|
||||
bool SkGpuDevice::bindDeviceAsTexture(SkPoint* max) {
|
||||
if (NULL != fTexture) {
|
||||
fContext->setTexture(fTexture);
|
||||
fContext->setTexture(0, fTexture);
|
||||
if (NULL != max) {
|
||||
max->set(SkFixedToScalar((width() << 16) /
|
||||
fTexture->allocWidth()),
|
||||
@ -431,7 +431,7 @@ void SkGpuDevice::AutoPaintShader::init(SkGpuDevice* device,
|
||||
}
|
||||
|
||||
// the lock has already called setTexture for us
|
||||
ctx->setSamplerState(samplerState);
|
||||
ctx->setSamplerState(0, samplerState);
|
||||
|
||||
// since our texture coords will be in local space, we wack the texture
|
||||
// matrix to map them back into 0...1 before we load it
|
||||
@ -456,7 +456,7 @@ void SkGpuDevice::AutoPaintShader::init(SkGpuDevice* device,
|
||||
}
|
||||
GrMatrix grmat;
|
||||
SkGr::SkMatrix2GrMatrix(matrix, &grmat);
|
||||
ctx->setTextureMatrix(grmat);
|
||||
ctx->setTextureMatrix(0, grmat);
|
||||
|
||||
// since we're going to use a shader/texture, we don't want the color,
|
||||
// just its alpha
|
||||
@ -507,7 +507,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
}
|
||||
|
||||
GrVertexLayout layout = shader.useTex() ?
|
||||
GrDrawTarget::kPositionAsTexCoord_VertexLayoutBit :
|
||||
GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0) :
|
||||
0;
|
||||
#if SK_SCALAR_IS_GR_SCALAR
|
||||
fContext->setVertexSourceToArray(pts, layout);
|
||||
@ -700,7 +700,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
|
||||
|
||||
GrSamplerState sampler(paint.isFilterBitmap()); // defaults to clamp
|
||||
// the lock has already called setTexture for us
|
||||
fContext->setSamplerState(sampler);
|
||||
fContext->setSamplerState(0, sampler);
|
||||
|
||||
GrTexture* texture;
|
||||
SkAutoCachedTexture act(this, bitmap, sampler, &texture);
|
||||
@ -708,7 +708,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
|
||||
return;
|
||||
}
|
||||
|
||||
GrVertexLayout layout = GrDrawTarget::kSeparateTexCoord_VertexLayoutBit;
|
||||
GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
|
||||
|
||||
GrPoint* vertex;
|
||||
if (!fContext->reserveAndLockGeometry(layout, 4,
|
||||
@ -734,7 +734,7 @@ void SkGpuDevice::internalDrawBitmap(const SkDraw& draw,
|
||||
texture->allocHeight());
|
||||
vertex[1].setRectFan(left, top, right, bottom, 2*sizeof(GrPoint));
|
||||
|
||||
fContext->setTextureMatrix(GrMatrix::I());
|
||||
fContext->setTextureMatrix(0, GrMatrix::I());
|
||||
// now draw the mesh
|
||||
sk_gr_set_paint(fContext, paint, true);
|
||||
fContext->drawNonIndexed(GrGpu::kTriangleFan_PrimitiveType, 0, 4);
|
||||
@ -746,11 +746,11 @@ static void gl_drawSprite(GrContext* ctx,
|
||||
const SkPaint& paint) {
|
||||
GrAutoViewMatrix avm(ctx, GrMatrix::I());
|
||||
|
||||
ctx->setSamplerState(GrSamplerState::ClampNoFilter());
|
||||
ctx->setTextureMatrix(GrMatrix::I());
|
||||
ctx->setSamplerState(0, GrSamplerState::ClampNoFilter());
|
||||
ctx->setTextureMatrix(0, GrMatrix::I());
|
||||
|
||||
GrPoint* vertex;
|
||||
GrVertexLayout layout = GrGpu::kSeparateTexCoord_VertexLayoutBit;
|
||||
GrVertexLayout layout = GrGpu::StageTexCoordVertexLayoutBit(0, 0);
|
||||
if (!ctx->reserveAndLockGeometry(layout, 4, 0,
|
||||
GrTCast<void**>(&vertex), NULL)) {
|
||||
return;
|
||||
@ -837,7 +837,7 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
bool releaseVerts = false;
|
||||
GrVertexLayout layout = 0;
|
||||
if (useTexture) {
|
||||
layout |= GrDrawTarget::kSeparateTexCoord_VertexLayoutBit;
|
||||
layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(0, 0);
|
||||
}
|
||||
if (NULL != colors) {
|
||||
layout |= GrDrawTarget::kColor_VertexLayoutBit;
|
||||
@ -855,16 +855,17 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
|
||||
&verts, NULL)) {
|
||||
return;
|
||||
}
|
||||
int texOffset, colorOffset;
|
||||
uint32_t stride = GrDrawTarget::VertexSizeAndOffsets(layout,
|
||||
&texOffset,
|
||||
&colorOffset);
|
||||
int texOffsets[GrDrawTarget::kNumStages];
|
||||
int colorOffset;
|
||||
uint32_t stride = GrDrawTarget::VertexSizeAndOffsetsByStage(layout,
|
||||
texOffsets,
|
||||
&colorOffset);
|
||||
for (int i = 0; i < vertexCount; ++i) {
|
||||
GrPoint* p = (GrPoint*)((intptr_t)verts + i * stride);
|
||||
p->set(SkScalarToGrScalar(vertices[i].fX),
|
||||
SkScalarToGrScalar(vertices[i].fY));
|
||||
if (texOffset > 0) {
|
||||
GrPoint* t = (GrPoint*)((intptr_t)p + texOffset);
|
||||
if (texOffsets[0] > 0) {
|
||||
GrPoint* t = (GrPoint*)((intptr_t)p + texOffsets[0]);
|
||||
t->set(SkScalarToGrScalar(texs[i].fX),
|
||||
SkScalarToGrScalar(texs[i].fY));
|
||||
}
|
||||
@ -1030,7 +1031,7 @@ SkGpuDevice::TexCache* SkGpuDevice::lockCachedTexture(const SkBitmap& bitmap,
|
||||
|
||||
if (NULL != entry) {
|
||||
newTexture = entry->texture();
|
||||
ctx->setTexture(newTexture);
|
||||
ctx->setTexture(0, newTexture);
|
||||
if (texture) {
|
||||
*texture = newTexture;
|
||||
}
|
||||
|
@ -225,7 +225,6 @@
|
||||
<ClCompile Include="..\..\gpu\src\GrMatrix.cpp" />
|
||||
<ClCompile Include="..\..\gpu\src\GrMemory.cpp" />
|
||||
<ClCompile Include="..\..\gpu\src\GrPath.cpp" />
|
||||
<ClCompile Include="..\..\gpu\src\GrPrintf_printf.cpp" />
|
||||
<ClCompile Include="..\..\gpu\src\GrRectanizer.cpp" />
|
||||
<ClCompile Include="..\..\gpu\src\GrTextContext.cpp" />
|
||||
<ClCompile Include="..\..\gpu\src\GrTextStrike.cpp" />
|
||||
@ -407,6 +406,7 @@
|
||||
<ClCompile Include="..\..\src\effects\SkRectShape.cpp" />
|
||||
<ClCompile Include="..\..\src\effects\SkTableMaskFilter.cpp" />
|
||||
<ClCompile Include="..\..\src\effects\SkTransparentShader.cpp" />
|
||||
<ClCompile Include="..\..\src\gpu\GrPrintf_skia.cpp" />
|
||||
<ClCompile Include="..\..\src\gpu\SkGpuCanvas.cpp" />
|
||||
<ClCompile Include="..\..\src\gpu\SkGpuDevice.cpp" />
|
||||
<ClCompile Include="..\..\src\gpu\SkGr.cpp" />
|
||||
|
Loading…
Reference in New Issue
Block a user