зеркало из https://github.com/mozilla/moz-skia.git
Use GrCustomStage to implement color matrix.
R=robertphillips@google.com Review URL: https://codereview.appspot.com/6716044 git-svn-id: http://skia.googlecode.com/svn/trunk@5975 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
1947ba6b9e
Коммит
67e78c9e47
|
@ -15,6 +15,8 @@
|
|||
#include "SkXfermode.h"
|
||||
|
||||
class SkBitmap;
|
||||
class GrCustomStage;
|
||||
class GrContext;
|
||||
|
||||
class SK_API SkColorFilter : public SkFlattenable {
|
||||
public:
|
||||
|
@ -113,6 +115,11 @@ public:
|
|||
*/
|
||||
static SkColorFilter* CreateLightingFilter(SkColor mul, SkColor add);
|
||||
|
||||
/** A subclass may implement this factory function to work with the GPU backend. If the return
|
||||
is non-NULL then the caller owns a ref on the returned object.
|
||||
*/
|
||||
virtual GrCustomStage* asNewCustomStage(GrContext*) const;
|
||||
|
||||
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
|
||||
protected:
|
||||
SkColorFilter() {}
|
||||
|
|
|
@ -39,6 +39,12 @@ public:
|
|||
void setSaturation(SkScalar sat);
|
||||
void setRGB2YUV();
|
||||
void setYUV2RGB();
|
||||
|
||||
bool operator==(const SkColorMatrix& other) const {
|
||||
return 0 == memcmp(fMat, other.fMat, sizeof(fMat));
|
||||
}
|
||||
|
||||
bool operator!=(const SkColorMatrix& other) const { return !((*this) == other); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,9 @@ public:
|
|||
virtual void filterSpan16(const uint16_t src[], int count, uint16_t[]) SK_OVERRIDE;
|
||||
virtual uint32_t getFlags() SK_OVERRIDE;
|
||||
virtual bool asColorMatrix(SkScalar matrix[20]) SK_OVERRIDE;
|
||||
#if SK_SUPPORT_GPU
|
||||
virtual GrCustomStage* asNewCustomStage(GrContext*) const SK_OVERRIDE;
|
||||
#endif
|
||||
|
||||
struct State {
|
||||
int32_t fArray[20];
|
||||
|
|
|
@ -58,7 +58,7 @@ private:
|
|||
|
||||
/** GrCustomStage subclasses should insert this macro in their implemenation file. They must then
|
||||
* also implement this static function:
|
||||
* GrCustomStage* CreateStage(SkRandom*, GrContext*, GrTexture* dummyTextures[2]);
|
||||
* GrCustomStage* TestCreate(SkRandom*, GrContext*, GrTexture* dummyTextures[2]);
|
||||
* dummyTextures[] are valied textures that they can optionally use for their texture accesses. The
|
||||
* first texture has config kSkia8888_PM_GrPixelConfig and the second has kAlpha_8_GrPixelConfig.
|
||||
* TestCreate functions are also free to create additional textures using the GrContext.
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
* The primitive color computation starts with the color specified by setColor(). This color is the
|
||||
* input to the first color stage. Each color stage feeds its output to the next color stage. The
|
||||
* final color stage's output color is input to the color filter specified by
|
||||
* setXfermodeColorFilter which it turn feeds into the color matrix. The output of the color matrix
|
||||
* is the final source color, S.
|
||||
* setXfermodeColorFilter which produces the final source color, S.
|
||||
*
|
||||
* Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
|
||||
* by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
|
||||
|
@ -40,7 +39,7 @@
|
|||
* Note that the coverage is applied after the blend. This is why they are computed as distinct
|
||||
* values.
|
||||
*
|
||||
* TODO: Encapsulate setXfermodeColorFilter and color matrix in stages and remove from GrPaint.
|
||||
* TODO: Encapsulate setXfermodeColorFilter in a GrCustomStage and remove from GrPaint.
|
||||
*/
|
||||
class GrPaint {
|
||||
public:
|
||||
|
@ -104,28 +103,11 @@ public:
|
|||
GrColor getColorFilterColor() const { return fColorFilterColor; }
|
||||
|
||||
/**
|
||||
* Turns off application of a color matrix. By default the color matrix is disabled.
|
||||
*/
|
||||
void disableColorMatrix() { fColorMatrixEnabled = false; }
|
||||
|
||||
/**
|
||||
* Specifies and enables a 4 x 5 color matrix.
|
||||
*/
|
||||
void setColorMatrix(const float matrix[20]) {
|
||||
fColorMatrixEnabled = true;
|
||||
memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
|
||||
}
|
||||
|
||||
bool isColorMatrixEnabled() const { return fColorMatrixEnabled; }
|
||||
const float* getColorMatrix() const { return fColorMatrix; }
|
||||
|
||||
/**
|
||||
* Disables both the matrix and SkXfermode::Mode color filters.
|
||||
* Disables the SkXfermode::Mode color filter.
|
||||
*/
|
||||
void resetColorFilter() {
|
||||
fColorFilterXfermode = SkXfermode::kDst_Mode;
|
||||
fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
|
||||
fColorMatrixEnabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,10 +228,6 @@ public:
|
|||
|
||||
fColorFilterColor = paint.fColorFilterColor;
|
||||
fColorFilterXfermode = paint.fColorFilterXfermode;
|
||||
fColorMatrixEnabled = paint.fColorMatrixEnabled;
|
||||
if (fColorMatrixEnabled) {
|
||||
memcpy(fColorMatrix, paint.fColorMatrix, sizeof(fColorMatrix));
|
||||
}
|
||||
|
||||
for (int i = 0; i < kMaxColorStages; ++i) {
|
||||
if (paint.isColorStageEnabled(i)) {
|
||||
|
@ -295,14 +273,12 @@ private:
|
|||
GrBlendCoeff fDstBlendCoeff;
|
||||
bool fAntiAlias;
|
||||
bool fDither;
|
||||
bool fColorMatrixEnabled;
|
||||
|
||||
GrColor fColor;
|
||||
uint8_t fCoverage;
|
||||
|
||||
GrColor fColorFilterColor;
|
||||
SkXfermode::Mode fColorFilterXfermode;
|
||||
float fColorMatrix[20];
|
||||
|
||||
void resetBlend() {
|
||||
fSrcBlendCoeff = kOne_GrBlendCoeff;
|
||||
|
|
|
@ -40,6 +40,10 @@ SkColor SkColorFilter::filterColor(SkColor c) {
|
|||
return SkUnPreMultiply::PMColorToColor(dst);
|
||||
}
|
||||
|
||||
GrCustomStage* SkColorFilter::asNewCustomStage(GrContext*) const {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SkFilterShader::SkFilterShader(SkShader* shader, SkColorFilter* filter) {
|
||||
|
|
|
@ -317,3 +317,115 @@ bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrCustomStage.h"
|
||||
#include "gl/GrGLProgramStage.h"
|
||||
|
||||
class ColorMatrixEffect : public GrCustomStage {
|
||||
public:
|
||||
static const char* Name() { return "Color Matrix"; }
|
||||
|
||||
ColorMatrixEffect(const SkColorMatrix& matrix) : GrCustomStage(0), fMatrix(matrix) {}
|
||||
|
||||
virtual const GrProgramStageFactory& getFactory() const SK_OVERRIDE {
|
||||
return GrTProgramStageFactory<ColorMatrixEffect>::getInstance();
|
||||
}
|
||||
|
||||
virtual bool isEqual(const GrCustomStage& s) const {
|
||||
const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(s);
|
||||
return cme.fMatrix == fMatrix;
|
||||
}
|
||||
|
||||
GR_DECLARE_CUSTOM_STAGE_TEST;
|
||||
|
||||
class GLProgramStage : public GrGLProgramStage {
|
||||
public:
|
||||
// this class always generates the same code.
|
||||
static StageKey GenKey(const GrCustomStage& s, const GrGLCaps&) { return 0; }
|
||||
|
||||
GLProgramStage(const GrProgramStageFactory& factory,
|
||||
const GrCustomStage& stage)
|
||||
: GrGLProgramStage(factory)
|
||||
, fMatrixHandle(GrGLUniformManager::kInvalidUniformHandle)
|
||||
, fVectorHandle(GrGLUniformManager::kInvalidUniformHandle) {
|
||||
}
|
||||
|
||||
virtual void setupVariables(GrGLShaderBuilder* builder) SK_OVERRIDE {
|
||||
fMatrixHandle = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
|
||||
kMat44f_GrSLType,
|
||||
"ColorMatrix");
|
||||
fVectorHandle = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
|
||||
kVec4f_GrSLType,
|
||||
"ColorMatrixVector");
|
||||
}
|
||||
|
||||
virtual void emitVS(GrGLShaderBuilder* builder, const char* vertexCoords) SK_OVERRIDE {
|
||||
}
|
||||
|
||||
virtual void emitFS(GrGLShaderBuilder* builder,
|
||||
const char* outputColor,
|
||||
const char* inputColor,
|
||||
const TextureSamplerArray&) SK_OVERRIDE {
|
||||
if (NULL == inputColor) {
|
||||
// could optimize this case, but we aren't for now.
|
||||
inputColor = GrGLSLOnesVecf(4);
|
||||
}
|
||||
// The max() is to guard against 0 / 0 during unpremul when the incoming color is
|
||||
// transparent black.
|
||||
builder->fFSCode.appendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n", inputColor);
|
||||
builder->fFSCode.appendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZeroAlpha) + %s;\n",
|
||||
outputColor,
|
||||
builder->getUniformCStr(fMatrixHandle),
|
||||
inputColor,
|
||||
builder->getUniformCStr(fVectorHandle));
|
||||
builder->fFSCode.appendf("\t%s.rgb *= %s.a;\n", outputColor, outputColor);
|
||||
}
|
||||
|
||||
virtual void setData(const GrGLUniformManager& uniManager,
|
||||
const GrCustomStage& stage,
|
||||
const GrRenderTarget*,
|
||||
int /* stageNum */) SK_OVERRIDE {
|
||||
const ColorMatrixEffect& cme = static_cast<const ColorMatrixEffect&>(stage);
|
||||
const float* m = cme.fMatrix.fMat;
|
||||
// The GL matrix is transposed from SkColorMatrix.
|
||||
GrGLfloat mt[] = {
|
||||
m[0], m[5], m[10], m[15],
|
||||
m[1], m[6], m[11], m[16],
|
||||
m[2], m[7], m[12], m[17],
|
||||
m[3], m[8], m[13], m[18],
|
||||
};
|
||||
static const float kScale = 1.0f / 255.0f;
|
||||
GrGLfloat vec[] = {
|
||||
m[4] * kScale, m[9] * kScale, m[14] * kScale, m[19] * kScale,
|
||||
};
|
||||
uniManager.setMatrix4fv(fMatrixHandle, 0, 1, mt);
|
||||
uniManager.set4fv(fVectorHandle, 0, 1, vec);
|
||||
}
|
||||
|
||||
private:
|
||||
GrGLUniformManager::UniformHandle fMatrixHandle;
|
||||
GrGLUniformManager::UniformHandle fVectorHandle;
|
||||
};
|
||||
|
||||
private:
|
||||
SkColorMatrix fMatrix;
|
||||
};
|
||||
|
||||
GR_DEFINE_CUSTOM_STAGE_TEST(ColorMatrixEffect);
|
||||
|
||||
GrCustomStage* ColorMatrixEffect::TestCreate(SkRandom* random,
|
||||
GrContext*,
|
||||
GrTexture* dummyTextures[2]) {
|
||||
SkColorMatrix colorMatrix;
|
||||
for (int i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) {
|
||||
colorMatrix.fMat[i] = random->nextSScalar1();
|
||||
}
|
||||
return SkNEW_ARGS(ColorMatrixEffect, (colorMatrix));
|
||||
}
|
||||
|
||||
GrCustomStage* SkColorMatrixFilter::asNewCustomStage(GrContext*) const {
|
||||
return SkNEW_ARGS(ColorMatrixEffect, (fMatrix));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -36,12 +36,6 @@ void GrDrawState::setFromPaint(const GrPaint& paint) {
|
|||
this->setState(GrDrawState::kDither_StateBit, paint.isDither());
|
||||
this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
|
||||
|
||||
if (paint.isColorMatrixEnabled()) {
|
||||
this->enableState(GrDrawState::kColorMatrix_StateBit);
|
||||
this->setColorMatrix(paint.getColorMatrix());
|
||||
} else {
|
||||
this->disableState(GrDrawState::kColorMatrix_StateBit);
|
||||
}
|
||||
this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
|
||||
this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode());
|
||||
this->setCoverage(paint.getCoverage());
|
||||
|
|
|
@ -650,22 +650,6 @@ public:
|
|||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// @name Color Matrix
|
||||
////
|
||||
|
||||
/**
|
||||
* Sets the color matrix to use for the next draw.
|
||||
* @param matrix the 5x4 matrix to apply to the incoming color
|
||||
*/
|
||||
void setColorMatrix(const float matrix[20]) {
|
||||
memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
|
||||
}
|
||||
|
||||
const float* getColorMatrix() const { return fColorMatrix; }
|
||||
|
||||
/// @}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// @name Edge AA
|
||||
// Edge equations can be specified to perform anti-aliasing. Because the
|
||||
|
@ -743,11 +727,6 @@ public:
|
|||
* operations.
|
||||
*/
|
||||
kNoColorWrites_StateBit = 0x08,
|
||||
/**
|
||||
* Draws will apply the color matrix, otherwise the color matrix is
|
||||
* ignored.
|
||||
*/
|
||||
kColorMatrix_StateBit = 0x10,
|
||||
|
||||
// Users of the class may add additional bits to the vector
|
||||
kDummyStateBit,
|
||||
|
@ -878,14 +857,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (kColorMatrix_StateBit & s.fFlagBits) {
|
||||
if (memcmp(fColorMatrix,
|
||||
s.fColorMatrix,
|
||||
sizeof(fColorMatrix))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool operator !=(const GrDrawState& s) const { return !(*this == s); }
|
||||
|
@ -914,10 +885,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (kColorMatrix_StateBit & s.fFlagBits) {
|
||||
memcpy(this->fColorMatrix, s.fColorMatrix, sizeof(fColorMatrix));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -942,8 +909,6 @@ private:
|
|||
// This field must be last; it will not be copied or compared
|
||||
// if the corresponding fTexture[] is NULL.
|
||||
GrSamplerState fSamplerStates[kNumStages];
|
||||
// only compared if the color matrix enable flag is set
|
||||
float fColorMatrix[20]; // 5 x 4 matrix
|
||||
|
||||
typedef GrRefCnt INHERITED;
|
||||
};
|
||||
|
|
|
@ -500,28 +500,37 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
|
|||
grPaint->setColor(SkColor2GrColor(skPaint.getColor()));
|
||||
GrAssert(!grPaint->isColorStageEnabled(kShaderTextureIdx));
|
||||
}
|
||||
|
||||
SkColorFilter* colorFilter = skPaint.getColorFilter();
|
||||
SkColor color;
|
||||
SkXfermode::Mode filterMode;
|
||||
SkScalar matrix[20];
|
||||
SkBitmap colorTransformTable;
|
||||
// TODO: SkColorFilter::asCustomStage()
|
||||
if (colorFilter != NULL && colorFilter->asColorMode(&color, &filterMode)) {
|
||||
if (!constantColor) {
|
||||
grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(color));
|
||||
} else {
|
||||
if (NULL != colorFilter) {
|
||||
// if the source color is a constant then apply the filter here once rather than per pixel
|
||||
// in a shader.
|
||||
if (constantColor) {
|
||||
SkColor filtered = colorFilter->filterColor(skPaint.getColor());
|
||||
grPaint->setColor(SkColor2GrColor(filtered));
|
||||
} else {
|
||||
SkAutoTUnref<GrCustomStage> stage(colorFilter->asNewCustomStage(dev->context()));
|
||||
if (NULL != stage.get()) {
|
||||
grPaint->colorSampler(kColorFilterTextureIdx)->setCustomStage(stage);
|
||||
} else {
|
||||
// TODO: rewrite these using asNewCustomStage()
|
||||
SkColor color;
|
||||
SkXfermode::Mode filterMode;
|
||||
SkBitmap colorTransformTable;
|
||||
if (colorFilter->asColorMode(&color, &filterMode)) {
|
||||
grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(color));
|
||||
} else if (colorFilter != NULL &&
|
||||
colorFilter->asComponentTable(&colorTransformTable)) {
|
||||
// pass NULL because the color table effect doesn't use tiling or filtering.
|
||||
GrTexture* texture = act->set(dev, colorTransformTable, NULL);
|
||||
GrSamplerState* colorSampler = grPaint->colorSampler(kColorFilterTextureIdx);
|
||||
colorSampler->reset();
|
||||
colorSampler->setCustomStage(SkNEW_ARGS(GrColorTableEffect, (texture)))->unref();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (colorFilter != NULL && colorFilter->asColorMatrix(matrix)) {
|
||||
grPaint->setColorMatrix(matrix);
|
||||
} else if (colorFilter != NULL && colorFilter->asComponentTable(&colorTransformTable)) {
|
||||
// pass NULL because the color table effect doesn't use tiling or filtering.
|
||||
GrTexture* texture = act->set(dev, colorTransformTable, NULL);
|
||||
GrSamplerState* colorSampler = grPaint->colorSampler(kColorFilterTextureIdx);
|
||||
colorSampler->reset();
|
||||
colorSampler->setCustomStage(SkNEW_ARGS(GrColorTableEffect, (texture)))->unref();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -511,7 +511,6 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
|
|||
#endif
|
||||
|
||||
SkXfermode::Coeff colorCoeff, uniformCoeff;
|
||||
bool applyColorMatrix = SkToBool(fDesc.fColorMatrixEnabled);
|
||||
// The rest of transfer mode color filters have not been implemented
|
||||
if (fDesc.fColorFilterXfermode < SkXfermode::kCoeffModesCnt) {
|
||||
GR_DEBUGCODE(bool success =)
|
||||
|
@ -524,17 +523,15 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
|
|||
uniformCoeff = SkXfermode::kZero_Coeff;
|
||||
}
|
||||
|
||||
// no need to do the color filter / matrix at all if coverage is 0. The
|
||||
// output color is scaled by the coverage. All the dual source outputs are
|
||||
// scaled by the coverage as well.
|
||||
// no need to do the color filter if coverage is 0. The output color is scaled by the coverage.
|
||||
// All the dual source outputs are scaled by the coverage as well.
|
||||
if (Desc::kTransBlack_ColorInput == fDesc.fCoverageInput) {
|
||||
colorCoeff = SkXfermode::kZero_Coeff;
|
||||
uniformCoeff = SkXfermode::kZero_Coeff;
|
||||
applyColorMatrix = false;
|
||||
}
|
||||
|
||||
// If we know the final color is going to be all zeros then we can
|
||||
// simplify the color filter coeffecients. needComputedColor will then
|
||||
// simplify the color filter coefficients. needComputedColor will then
|
||||
// come out false below.
|
||||
if (Desc::kTransBlack_ColorInput == fDesc.fColorInput) {
|
||||
colorCoeff = SkXfermode::kZero_Coeff;
|
||||
|
@ -664,8 +661,7 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
|
|||
}
|
||||
bool wroteFragColorZero = false;
|
||||
if (SkXfermode::kZero_Coeff == uniformCoeff &&
|
||||
SkXfermode::kZero_Coeff == colorCoeff &&
|
||||
!applyColorMatrix) {
|
||||
SkXfermode::kZero_Coeff == colorCoeff) {
|
||||
builder.fFSCode.appendf("\t%s = %s;\n",
|
||||
colorOutput.getName().c_str(),
|
||||
GrGLSLZerosVecf(4));
|
||||
|
@ -677,22 +673,6 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
|
|||
colorCoeff, colorFilterColorUniName, color);
|
||||
inColor = "filteredColor";
|
||||
}
|
||||
if (applyColorMatrix) {
|
||||
const char* colMatrixName;
|
||||
const char* colMatrixVecName;
|
||||
fUniforms.fColorMatrixUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
|
||||
kMat44f_GrSLType, "ColorMatrix",
|
||||
&colMatrixName);
|
||||
fUniforms.fColorMatrixVecUni = builder.addUniform(GrGLShaderBuilder::kFragment_ShaderType,
|
||||
kVec4f_GrSLType, "ColorMatrixVec",
|
||||
&colMatrixVecName);
|
||||
const char* color = adjustInColor(inColor);
|
||||
builder.fFSCode.appendf("\tvec4 matrixedColor = %s * vec4(%s.rgb / %s.a, %s.a) + %s;\n",
|
||||
colMatrixName, color, color, color, colMatrixVecName);
|
||||
builder.fFSCode.append("\tmatrixedColor.rgb *= matrixedColor.a;\n");
|
||||
|
||||
inColor = "matrixedColor";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// compute the partial coverage (coverage stages and edge aa)
|
||||
|
|
|
@ -155,7 +155,6 @@ public:
|
|||
uint8_t fDualSrcOutput; // casts to enum DualSrcOutput
|
||||
int8_t fFirstCoverageStage;
|
||||
SkBool8 fEmitsPointSize;
|
||||
SkBool8 fColorMatrixEnabled;
|
||||
|
||||
uint8_t fColorFilterXfermode; // casts to enum SkXfermode::Mode
|
||||
};
|
||||
|
@ -224,16 +223,12 @@ private:
|
|||
UniformHandle fColorUni;
|
||||
UniformHandle fCoverageUni;
|
||||
UniformHandle fColorFilterUni;
|
||||
UniformHandle fColorMatrixUni;
|
||||
UniformHandle fColorMatrixVecUni;
|
||||
StageUniforms fStages[GrDrawState::kNumStages];
|
||||
Uniforms() {
|
||||
fViewMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
|
||||
fColorUni = GrGLUniformManager::kInvalidUniformHandle;
|
||||
fCoverageUni = GrGLUniformManager::kInvalidUniformHandle;
|
||||
fColorFilterUni = GrGLUniformManager::kInvalidUniformHandle;
|
||||
fColorMatrixUni = GrGLUniformManager::kInvalidUniformHandle;
|
||||
fColorMatrixVecUni = GrGLUniformManager::kInvalidUniformHandle;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2020,10 +2020,12 @@ void GrGpuGL::flushBoundTextureAndParams(int stage) {
|
|||
GrDrawState* drawState = this->drawState();
|
||||
// FIXME: Assuming at most one texture per custom stage
|
||||
const GrCustomStage* customStage = drawState->sampler(stage)->getCustomStage();
|
||||
GrGLTexture* nextTexture = static_cast<GrGLTexture*>(customStage->texture(0));
|
||||
if (NULL != nextTexture) {
|
||||
const GrTextureParams& texParams = customStage->textureAccess(0).getParams();
|
||||
this->flushBoundTextureAndParams(stage, texParams, nextTexture);
|
||||
if (customStage->numTextures() > 0) {
|
||||
GrGLTexture* nextTexture = static_cast<GrGLTexture*>(customStage->texture(0));
|
||||
if (NULL != nextTexture) {
|
||||
const GrTextureParams& texParams = customStage->textureAccess(0).getParams();
|
||||
this->flushBoundTextureAndParams(stage, texParams, nextTexture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -229,14 +229,6 @@ private:
|
|||
// sets the MVP matrix uniform for currently bound program
|
||||
void flushViewMatrix(DrawType type);
|
||||
|
||||
// flushes the parameters to two point radial gradient
|
||||
void flushRadial2(int stage);
|
||||
|
||||
// flushes the parameters for convolution
|
||||
void flushConvolution(int stage);
|
||||
|
||||
// flushes the color matrix
|
||||
void flushColorMatrix();
|
||||
|
||||
// flushes dithering, color-mask, and face culling stat
|
||||
void flushMiscFixedFunctionState();
|
||||
|
@ -251,7 +243,7 @@ private:
|
|||
const GrCustomStage** customStages,
|
||||
ProgramDesc* desc);
|
||||
|
||||
// Inits GrDrawTarget::Caps, sublcass may enable additional caps.
|
||||
// Inits GrDrawTarget::Caps, subclass may enable additional caps.
|
||||
void initCaps();
|
||||
|
||||
void initFSAASupport();
|
||||
|
|
|
@ -200,6 +200,9 @@ void GrGpuGL::flushTextureMatrix(int s) {
|
|||
|
||||
// FIXME: Still assuming only a single texture per custom stage
|
||||
const GrCustomStage* stage = drawState.getSampler(s).getCustomStage();
|
||||
if (0 == stage->numTextures()) {
|
||||
return;
|
||||
}
|
||||
const GrGLTexture* texture = static_cast<const GrGLTexture*>(stage->texture(0));
|
||||
if (NULL != texture) {
|
||||
|
||||
|
@ -240,26 +243,6 @@ void GrGpuGL::flushTextureMatrix(int s) {
|
|||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::flushColorMatrix() {
|
||||
UniformHandle matrixUni = fCurrentProgram->fUniforms.fColorMatrixUni;
|
||||
UniformHandle vecUni = fCurrentProgram->fUniforms.fColorMatrixVecUni;
|
||||
if (kInvalidUniformHandle != matrixUni && kInvalidUniformHandle != vecUni) {
|
||||
const float* m = this->getDrawState().getColorMatrix();
|
||||
GrGLfloat mt[] = {
|
||||
m[0], m[5], m[10], m[15],
|
||||
m[1], m[6], m[11], m[16],
|
||||
m[2], m[7], m[12], m[17],
|
||||
m[3], m[8], m[13], m[18],
|
||||
};
|
||||
static float scale = 1.0f / 255.0f;
|
||||
GrGLfloat vec[] = {
|
||||
m[4] * scale, m[9] * scale, m[14] * scale, m[19] * scale,
|
||||
};
|
||||
fCurrentProgram->fUniformManager.setMatrix4f(matrixUni, mt);
|
||||
fCurrentProgram->fUniformManager.set4fv(vecUni, 0, 1, vec);
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::flushColor(GrColor color) {
|
||||
const ProgramDesc& desc = fCurrentProgram->getDesc();
|
||||
const GrDrawState& drawState = this->getDrawState();
|
||||
|
@ -414,7 +397,6 @@ bool GrGpuGL::flushGraphicsState(DrawType type) {
|
|||
}
|
||||
}
|
||||
}
|
||||
this->flushColorMatrix();
|
||||
}
|
||||
this->flushStencil(type);
|
||||
this->flushViewMatrix(type);
|
||||
|
@ -645,8 +627,6 @@ void GrGpuGL::buildProgram(bool isPoints,
|
|||
SkXfermode::kDst_Mode :
|
||||
drawState.getColorFilterMode();
|
||||
|
||||
desc->fColorMatrixEnabled = drawState.isStateFlagEnabled(GrDrawState::kColorMatrix_StateBit);
|
||||
|
||||
// no reason to do edge aa or look at per-vertex coverage if coverage is
|
||||
// ignored
|
||||
if (skipCoverage) {
|
||||
|
@ -701,16 +681,23 @@ void GrGpuGL::buildProgram(bool isPoints,
|
|||
const GrSamplerState& sampler = drawState.getSampler(s);
|
||||
// FIXME: Still assuming one texture per custom stage
|
||||
const GrCustomStage* customStage = drawState.getSampler(s).getCustomStage();
|
||||
const GrGLTexture* texture = static_cast<const GrGLTexture*>(customStage->texture(0));
|
||||
GrMatrix samplerMatrix;
|
||||
sampler.getTotalMatrix(&samplerMatrix);
|
||||
if (NULL != texture) {
|
||||
// We call this helper function rather then simply checking the client-specified
|
||||
// texture matrix. This is because we may have to concat a y-inversion to account
|
||||
// for texture orientation.
|
||||
stage.fOptFlags |= TextureMatrixOptFlags(texture, sampler);
|
||||
}
|
||||
|
||||
if (customStage->numTextures() > 0) {
|
||||
const GrGLTexture* texture =
|
||||
static_cast<const GrGLTexture*>(customStage->texture(0));
|
||||
GrMatrix samplerMatrix;
|
||||
sampler.getTotalMatrix(&samplerMatrix);
|
||||
if (NULL != texture) {
|
||||
// We call this helper function rather then simply checking the client-specified
|
||||
// texture matrix. This is because we may have to concat a y-inversion to account
|
||||
// for texture orientation.
|
||||
stage.fOptFlags |= TextureMatrixOptFlags(texture, sampler);
|
||||
}
|
||||
} else {
|
||||
// Set identity to do the minimal amount of extra work for the no texture case.
|
||||
// This will go away when custom stages manage their own texture matrix.
|
||||
stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
|
||||
}
|
||||
setup_custom_stage(&stage, sampler, this->glCaps(), customStages,
|
||||
fCurrentProgram.get(), s);
|
||||
|
||||
|
@ -724,7 +711,7 @@ void GrGpuGL::buildProgram(bool isPoints,
|
|||
desc->fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
|
||||
|
||||
// Currently the experimental GS will only work with triangle prims (and it doesn't do anything
|
||||
// other than pass through values fromthe VS to the FS anyway).
|
||||
// other than pass through values from the VS to the FS anyway).
|
||||
#if 0 && GR_GL_EXPERIMENTAL_GS
|
||||
desc->fExperimentalGS = this->getCaps().fGeometryShaderSupport;
|
||||
#endif
|
||||
|
|
|
@ -114,8 +114,6 @@ bool GrGpuGL::programUnitTest() {
|
|||
} else {
|
||||
}
|
||||
|
||||
pdesc.fColorMatrixEnabled = random_bool(&random);
|
||||
|
||||
if (this->getCaps().dualSourceBlendingSupport()) {
|
||||
pdesc.fDualSrcOutput = random_int(&random, ProgramDesc::kDualSrcOutputCnt);
|
||||
} else {
|
||||
|
@ -174,17 +172,17 @@ static void GLProgramsTest(skiatest::Reporter* reporter, GrContext* context) {
|
|||
REPORTER_ASSERT(reporter, shadersGpu->programUnitTest());
|
||||
}
|
||||
|
||||
|
||||
#include "TestClassDef.h"
|
||||
DEFINE_GPUTESTCLASS("GLPrograms", GLProgramsTestClass, GLProgramsTest)
|
||||
|
||||
// This is evil evil evil. The linker may throw away whole translation units as dead code if it
|
||||
// thinks none of the functions are called. It will do this even if there are static initilializers
|
||||
// thinks none of the functions are called. It will do this even if there are static initializers
|
||||
// in the unit that could pass pointers to functions from the unit out to other translation units!
|
||||
// We force some of the effects that would otherwise be discarded to link here.
|
||||
|
||||
#include "SkLightingImageFilter.h"
|
||||
#include "SkMagnifierImageFilter.h"
|
||||
#include "SkColorMatrixFilter.h"
|
||||
|
||||
void forceLinking();
|
||||
|
||||
|
@ -192,6 +190,8 @@ void forceLinking() {
|
|||
SkLightingImageFilter::CreateDistantLitDiffuse(SkPoint3(0,0,0), 0, 0, 0);
|
||||
SkMagnifierImageFilter mag(SkRect::MakeWH(SK_Scalar1, SK_Scalar1), SK_Scalar1);
|
||||
GrConfigConversionEffect::Create(NULL, false);
|
||||
SkScalar matrix[20];
|
||||
SkColorMatrixFilter cmf(matrix);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче