Swizzle shader output and blend when using GL_RED to implement kAlpha_8_GrPixelConfig
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1584473002 Review URL: https://codereview.chromium.org/1584473002
This commit is contained in:
parent
87a721b246
commit
7f9b2e4a45
@ -175,6 +175,7 @@
|
|||||||
'<(skia_src_path)/gpu/GrSoftwarePathRenderer.h',
|
'<(skia_src_path)/gpu/GrSoftwarePathRenderer.h',
|
||||||
'<(skia_src_path)/gpu/GrSurfacePriv.h',
|
'<(skia_src_path)/gpu/GrSurfacePriv.h',
|
||||||
'<(skia_src_path)/gpu/GrSurface.cpp',
|
'<(skia_src_path)/gpu/GrSurface.cpp',
|
||||||
|
'<(skia_src_path)/gpu/GrSwizzle.h',
|
||||||
'<(skia_src_path)/gpu/GrTexture.cpp',
|
'<(skia_src_path)/gpu/GrTexture.cpp',
|
||||||
'<(skia_src_path)/gpu/GrTextureParamsAdjuster.h',
|
'<(skia_src_path)/gpu/GrTextureParamsAdjuster.h',
|
||||||
'<(skia_src_path)/gpu/GrTextureParamsAdjuster.cpp',
|
'<(skia_src_path)/gpu/GrTextureParamsAdjuster.cpp',
|
||||||
|
@ -70,15 +70,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct KeyHeader {
|
struct KeyHeader {
|
||||||
uint8_t fFragPosKey; // set by GrGLShaderBuilder if there are
|
// Set by GrGLShaderBuilder if there are effects that read the fragment position. Otherwise,
|
||||||
// effects that read the fragment position.
|
// 0.
|
||||||
// Otherwise, 0.
|
uint8_t fFragPosKey;
|
||||||
|
// Set to uniquely idenitify any swizzling of the shader's output color(s).
|
||||||
|
uint8_t fOutputSwizzle;
|
||||||
uint8_t fSnapVerticesToPixelCenters;
|
uint8_t fSnapVerticesToPixelCenters;
|
||||||
int8_t fColorEffectCnt;
|
int8_t fColorEffectCnt;
|
||||||
int8_t fCoverageEffectCnt;
|
int8_t fCoverageEffectCnt;
|
||||||
uint8_t fIgnoresCoverage;
|
uint8_t fIgnoresCoverage;
|
||||||
};
|
};
|
||||||
GR_STATIC_ASSERT(sizeof(KeyHeader) == 5);
|
|
||||||
|
|
||||||
int numColorEffects() const {
|
int numColorEffects() const {
|
||||||
return this->header().fColorEffectCnt;
|
return this->header().fColorEffectCnt;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define GrSwizzle_DEFINED
|
#define GrSwizzle_DEFINED
|
||||||
|
|
||||||
#include "GrTypes.h"
|
#include "GrTypes.h"
|
||||||
|
#include "GrColor.h"
|
||||||
|
|
||||||
/** Represents a rgba swizzle. It can be converted either into a string or a eight bit int.
|
/** Represents a rgba swizzle. It can be converted either into a string or a eight bit int.
|
||||||
Currently there is no way to specify an arbitrary swizzle, just some static swizzles and an
|
Currently there is no way to specify an arbitrary swizzle, just some static swizzles and an
|
||||||
@ -17,11 +18,23 @@ class GrSwizzle {
|
|||||||
public:
|
public:
|
||||||
GrSwizzle() { *this = RGBA(); }
|
GrSwizzle() { *this = RGBA(); }
|
||||||
|
|
||||||
|
GrSwizzle(const GrSwizzle& that) { *this = that; }
|
||||||
|
|
||||||
GrSwizzle& operator=(const GrSwizzle& that) {
|
GrSwizzle& operator=(const GrSwizzle& that) {
|
||||||
memcpy(this, &that, sizeof(GrSwizzle));
|
memcpy(this, &that, sizeof(GrSwizzle));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Recreates a GrSwizzle from the output of asKey() */
|
||||||
|
void setFromKey(uint8_t key) {
|
||||||
|
fKey = key;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
fSwiz[i] = IdxToChar(key & 3);
|
||||||
|
key >>= 2;
|
||||||
|
}
|
||||||
|
SkASSERT(fSwiz[4] == 0);
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const GrSwizzle& that) const { return this->asUInt() == that.asUInt(); }
|
bool operator==(const GrSwizzle& that) const { return this->asUInt() == that.asUInt(); }
|
||||||
|
|
||||||
bool operator!=(const GrSwizzle& that) const { return !(*this == that); }
|
bool operator!=(const GrSwizzle& that) const { return !(*this == that); }
|
||||||
@ -32,6 +45,25 @@ public:
|
|||||||
/** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */
|
/** 4 char null terminated string consisting only of chars 'r', 'g', 'b', 'a'. */
|
||||||
const char* c_str() const { return fSwiz; }
|
const char* c_str() const { return fSwiz; }
|
||||||
|
|
||||||
|
/** Applies this swizzle to the input color and returns the swizzled color. */
|
||||||
|
GrColor applyTo(GrColor color) const {
|
||||||
|
int idx;
|
||||||
|
uint32_t key = fKey;
|
||||||
|
// Index of the input color that should be mapped to output r.
|
||||||
|
idx = (key & 3);
|
||||||
|
uint32_t outR = (color >> idx * 8) & 0xFF;
|
||||||
|
key >>= 2;
|
||||||
|
idx = (key & 3);
|
||||||
|
uint32_t outG = (color >> idx * 8) & 0xFF;
|
||||||
|
key >>= 2;
|
||||||
|
idx = (key & 3);
|
||||||
|
uint32_t outB = (color >> idx * 8) & 0xFF;
|
||||||
|
key >>= 2;
|
||||||
|
idx = (key & 3);
|
||||||
|
uint32_t outA = (color >> idx * 8) & 0xFF;
|
||||||
|
return GrColorPackRGBA(outR, outG, outB, outA);
|
||||||
|
}
|
||||||
|
|
||||||
static const GrSwizzle& RGBA() {
|
static const GrSwizzle& RGBA() {
|
||||||
static GrSwizzle gRGBA("rgba");
|
static GrSwizzle gRGBA("rgba");
|
||||||
return gRGBA;
|
return gRGBA;
|
||||||
@ -59,19 +91,31 @@ private:
|
|||||||
static int CharToIdx(char c) {
|
static int CharToIdx(char c) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'r':
|
case 'r':
|
||||||
return 0;
|
return (GrColor_SHIFT_R / 8);
|
||||||
case 'g':
|
case 'g':
|
||||||
return 1;
|
return (GrColor_SHIFT_G / 8);
|
||||||
case 'b':
|
case 'b':
|
||||||
return 2;
|
return (GrColor_SHIFT_B / 8);
|
||||||
case 'a':
|
case 'a':
|
||||||
return 3;
|
return (GrColor_SHIFT_A / 8);
|
||||||
default:
|
default:
|
||||||
SkFAIL("Invalid swizzle char");
|
SkFAIL("Invalid swizzle char");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static /* constexpr */ char IToC(int idx) {
|
||||||
|
return (8*idx) == GrColor_SHIFT_R ? 'r' :
|
||||||
|
(8*idx) == GrColor_SHIFT_G ? 'g' :
|
||||||
|
(8*idx) == GrColor_SHIFT_B ? 'b' : 'a';
|
||||||
|
}
|
||||||
|
|
||||||
|
static char IdxToChar(int c) {
|
||||||
|
// Hopefully this array gets computed at compile time.
|
||||||
|
static const char gStr[4] = { IToC(0), IToC(1), IToC(2), IToC(3) };
|
||||||
|
return gStr[c];
|
||||||
|
}
|
||||||
|
|
||||||
explicit GrSwizzle(const char* str) {
|
explicit GrSwizzle(const char* str) {
|
||||||
SkASSERT(strlen(str) == 4);
|
SkASSERT(strlen(str) == 4);
|
||||||
fSwiz[0] = str[0];
|
fSwiz[0] = str[0];
|
||||||
|
@ -1548,6 +1548,19 @@ void GrGLCaps::initConfigTable(const GrGLContextInfo& ctxInfo, const GrGLInterfa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shader output swizzles will default to RGBA. When we've use GL_RED instead of GL_ALPHA to
|
||||||
|
// implement kAlpha_8_GrPixelConfig we need to swizzle the shader outputs so the alpha channel
|
||||||
|
// gets written to the single component.
|
||||||
|
if (this->textureRedSupport()) {
|
||||||
|
for (int i = 0; i < kGrPixelConfigCnt; ++i) {
|
||||||
|
GrPixelConfig config = static_cast<GrPixelConfig>(i);
|
||||||
|
if (GrPixelConfigIsAlphaOnly(config) &&
|
||||||
|
fConfigTable[i].fFormats.fBaseInternalFormat == GR_GL_RED) {
|
||||||
|
glslCaps->fConfigOutputSwizzle[i] = GrSwizzle::AAAA();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
// Make sure we initialized everything.
|
// Make sure we initialized everything.
|
||||||
ConfigInfo defaultEntry;
|
ConfigInfo defaultEntry;
|
||||||
|
@ -1570,7 +1570,10 @@ bool GrGLGpu::flushGLState(const DrawArgs& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (blendInfo.fWriteColor) {
|
if (blendInfo.fWriteColor) {
|
||||||
this->flushBlend(blendInfo);
|
// Swizzle the blend to match what the shader will output.
|
||||||
|
const GrSwizzle& swizzle = this->glCaps().glslCaps()->configOutputSwizzle(
|
||||||
|
args.fPipeline->getRenderTarget()->config());
|
||||||
|
this->flushBlend(blendInfo, swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkSTArray<8, const GrTextureAccess*> textureAccesses;
|
SkSTArray<8, const GrTextureAccess*> textureAccesses;
|
||||||
@ -1650,7 +1653,7 @@ void GrGLGpu::setupGeometry(const GrPrimitiveProcessor& primProc,
|
|||||||
void GrGLGpu::buildProgramDesc(GrProgramDesc* desc,
|
void GrGLGpu::buildProgramDesc(GrProgramDesc* desc,
|
||||||
const GrPrimitiveProcessor& primProc,
|
const GrPrimitiveProcessor& primProc,
|
||||||
const GrPipeline& pipeline) const {
|
const GrPipeline& pipeline) const {
|
||||||
if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, this)) {
|
if (!GrGLProgramDescBuilder::Build(desc, primProc, pipeline, *this->glCaps().glslCaps())) {
|
||||||
SkDEBUGFAIL("Failed to generate GL program descriptor");
|
SkDEBUGFAIL("Failed to generate GL program descriptor");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2395,7 +2398,7 @@ void GrGLGpu::flushHWAAState(GrRenderTarget* rt, bool useHWAA) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo) {
|
void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle& swizzle) {
|
||||||
// Any optimization to disable blending should have already been applied and
|
// Any optimization to disable blending should have already been applied and
|
||||||
// tweaked the equation to "add" or "subtract", and the coeffs to (1, 0).
|
// tweaked the equation to "add" or "subtract", and the coeffs to (1, 0).
|
||||||
|
|
||||||
@ -2448,15 +2451,16 @@ void GrGLGpu::flushBlend(const GrXferProcessor::BlendInfo& blendInfo) {
|
|||||||
fHWBlendState.fDstCoeff = dstCoeff;
|
fHWBlendState.fDstCoeff = dstCoeff;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrColor blendConst = blendInfo.fBlendConstant;
|
if ((BlendCoeffReferencesConstant(srcCoeff) || BlendCoeffReferencesConstant(dstCoeff))) {
|
||||||
if ((BlendCoeffReferencesConstant(srcCoeff) ||
|
GrColor blendConst = blendInfo.fBlendConstant;
|
||||||
BlendCoeffReferencesConstant(dstCoeff)) &&
|
blendConst = swizzle.applyTo(blendConst);
|
||||||
(!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst)) {
|
if (!fHWBlendState.fConstColorValid || fHWBlendState.fConstColor != blendConst) {
|
||||||
GrGLfloat c[4];
|
GrGLfloat c[4];
|
||||||
GrColorToRGBAFloat(blendConst, c);
|
GrColorToRGBAFloat(blendConst, c);
|
||||||
GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
|
GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
|
||||||
fHWBlendState.fConstColor = blendConst;
|
fHWBlendState.fConstColor = blendConst;
|
||||||
fHWBlendState.fConstColorValid = true;
|
fHWBlendState.fConstColorValid = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2840,6 +2844,12 @@ bool GrGLGpu::onCopySurface(GrSurface* dst,
|
|||||||
GrSurface* src,
|
GrSurface* src,
|
||||||
const SkIRect& srcRect,
|
const SkIRect& srcRect,
|
||||||
const SkIPoint& dstPoint) {
|
const SkIPoint& dstPoint) {
|
||||||
|
// None of our copy methods can handle a swizzle. TODO: Make copySurfaceAsDraw handle the
|
||||||
|
// swizzle.
|
||||||
|
if (this->glCaps().glslCaps()->configOutputSwizzle(src->config()) !=
|
||||||
|
this->glCaps().glslCaps()->configOutputSwizzle(dst->config())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (src->asTexture() && dst->asRenderTarget()) {
|
if (src->asTexture() && dst->asRenderTarget()) {
|
||||||
this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
|
this->copySurfaceAsDraw(dst, src, srcRect, dstPoint);
|
||||||
return true;
|
return true;
|
||||||
@ -3064,6 +3074,9 @@ void GrGLGpu::createWireRectProgram() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) {
|
void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) {
|
||||||
|
// TODO: This should swizzle the output to match dst's config, though it is a debugging
|
||||||
|
// visualization.
|
||||||
|
|
||||||
this->handleDirtyContext();
|
this->handleDirtyContext();
|
||||||
if (!fWireRectProgram.fProgram) {
|
if (!fWireRectProgram.fProgram) {
|
||||||
this->createWireRectProgram();
|
this->createWireRectProgram();
|
||||||
@ -3114,7 +3127,7 @@ void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor
|
|||||||
|
|
||||||
GrXferProcessor::BlendInfo blendInfo;
|
GrXferProcessor::BlendInfo blendInfo;
|
||||||
blendInfo.reset();
|
blendInfo.reset();
|
||||||
this->flushBlend(blendInfo);
|
this->flushBlend(blendInfo, GrSwizzle::RGBA());
|
||||||
this->flushColorWrite(true);
|
this->flushColorWrite(true);
|
||||||
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
|
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
|
||||||
this->flushHWAAState(glRT, false);
|
this->flushHWAAState(glRT, false);
|
||||||
@ -3185,7 +3198,7 @@ void GrGLGpu::copySurfaceAsDraw(GrSurface* dst,
|
|||||||
|
|
||||||
GrXferProcessor::BlendInfo blendInfo;
|
GrXferProcessor::BlendInfo blendInfo;
|
||||||
blendInfo.reset();
|
blendInfo.reset();
|
||||||
this->flushBlend(blendInfo);
|
this->flushBlend(blendInfo, GrSwizzle::RGBA());
|
||||||
this->flushColorWrite(true);
|
this->flushColorWrite(true);
|
||||||
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
|
this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
|
||||||
this->flushHWAAState(dstRT, false);
|
this->flushHWAAState(dstRT, false);
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
class GrPipeline;
|
class GrPipeline;
|
||||||
class GrNonInstancedVertices;
|
class GrNonInstancedVertices;
|
||||||
|
class GrSwizzle;
|
||||||
|
|
||||||
#ifdef SK_DEVELOPER
|
#ifdef SK_DEVELOPER
|
||||||
#define PROGRAM_CACHE_STATS
|
#define PROGRAM_CACHE_STATS
|
||||||
@ -199,8 +200,7 @@ private:
|
|||||||
const GrNonInstancedVertices& vertices,
|
const GrNonInstancedVertices& vertices,
|
||||||
size_t* indexOffsetInBytes);
|
size_t* indexOffsetInBytes);
|
||||||
|
|
||||||
// Subclasses should call this to flush the blend state.
|
void flushBlend(const GrXferProcessor::BlendInfo& blendInfo, const GrSwizzle&);
|
||||||
void flushBlend(const GrXferProcessor::BlendInfo& blendInfo);
|
|
||||||
|
|
||||||
bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
|
bool hasExtension(const char* ext) const { return fGLContext->hasExtension(ext); }
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ static void add_texture_key(GrProcessorKeyBuilder* b, const GrProcessor& proc,
|
|||||||
* function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
|
* function because it is hairy, though FPs do not have attribs, and GPs do not have transforms
|
||||||
*/
|
*/
|
||||||
static bool gen_meta_key(const GrProcessor& proc,
|
static bool gen_meta_key(const GrProcessor& proc,
|
||||||
const GrGLCaps& caps,
|
const GrGLSLCaps& glslCaps,
|
||||||
uint32_t transformKey,
|
uint32_t transformKey,
|
||||||
GrProcessorKeyBuilder* b) {
|
GrProcessorKeyBuilder* b) {
|
||||||
size_t processorKeySize = b->size();
|
size_t processorKeySize = b->size();
|
||||||
@ -58,7 +58,7 @@ static bool gen_meta_key(const GrProcessor& proc,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_texture_key(b, proc, *caps.glslCaps());
|
add_texture_key(b, proc, glslCaps);
|
||||||
|
|
||||||
uint32_t* key = b->add32n(2);
|
uint32_t* key = b->add32n(2);
|
||||||
key[0] = (classID << 16) | SkToU32(processorKeySize);
|
key[0] = (classID << 16) | SkToU32(processorKeySize);
|
||||||
@ -68,25 +68,24 @@ static bool gen_meta_key(const GrProcessor& proc,
|
|||||||
|
|
||||||
static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
|
static bool gen_frag_proc_and_meta_keys(const GrPrimitiveProcessor& primProc,
|
||||||
const GrFragmentProcessor& fp,
|
const GrFragmentProcessor& fp,
|
||||||
const GrGLCaps& caps,
|
const GrGLSLCaps& glslCaps,
|
||||||
GrProcessorKeyBuilder* b) {
|
GrProcessorKeyBuilder* b) {
|
||||||
for (int i = 0; i < fp.numChildProcessors(); ++i) {
|
for (int i = 0; i < fp.numChildProcessors(); ++i) {
|
||||||
if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), caps, b)) {
|
if (!gen_frag_proc_and_meta_keys(primProc, fp.childProcessor(i), glslCaps, b)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fp.getGLSLProcessorKey(*caps.glslCaps(), b);
|
fp.getGLSLProcessorKey(glslCaps, b);
|
||||||
|
|
||||||
//**** use glslCaps here?
|
return gen_meta_key(fp, glslCaps, primProc.getTransformKey(fp.coordTransforms(),
|
||||||
return gen_meta_key(fp, caps, primProc.getTransformKey(fp.coordTransforms(),
|
fp.numTransformsExclChildren()), b);
|
||||||
fp.numTransformsExclChildren()), b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
|
bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
|
||||||
const GrPrimitiveProcessor& primProc,
|
const GrPrimitiveProcessor& primProc,
|
||||||
const GrPipeline& pipeline,
|
const GrPipeline& pipeline,
|
||||||
const GrGLGpu* gpu) {
|
const GrGLSLCaps& glslCaps) {
|
||||||
// The descriptor is used as a cache key. Thus when a field of the
|
// The descriptor is used as a cache key. Thus when a field of the
|
||||||
// descriptor will not affect program generation (because of the attribute
|
// descriptor will not affect program generation (because of the attribute
|
||||||
// bindings in use or other descriptor field settings) it should be set
|
// bindings in use or other descriptor field settings) it should be set
|
||||||
@ -101,25 +100,23 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
|
|||||||
|
|
||||||
GrProcessorKeyBuilder b(&glDesc->key());
|
GrProcessorKeyBuilder b(&glDesc->key());
|
||||||
|
|
||||||
primProc.getGLSLProcessorKey(*gpu->glCaps().glslCaps(), &b);
|
primProc.getGLSLProcessorKey(glslCaps, &b);
|
||||||
//**** use glslCaps here?
|
if (!gen_meta_key(primProc, glslCaps, 0, &b)) {
|
||||||
if (!gen_meta_key(primProc, gpu->glCaps(), 0, &b)) {
|
|
||||||
glDesc->key().reset();
|
glDesc->key().reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
|
for (int i = 0; i < pipeline.numFragmentProcessors(); ++i) {
|
||||||
const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i);
|
const GrFragmentProcessor& fp = pipeline.getFragmentProcessor(i);
|
||||||
if (!gen_frag_proc_and_meta_keys(primProc, fp, gpu->glCaps(), &b)) {
|
if (!gen_frag_proc_and_meta_keys(primProc, fp, glslCaps, &b)) {
|
||||||
glDesc->key().reset();
|
glDesc->key().reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
const GrXferProcessor& xp = pipeline.getXferProcessor();
|
||||||
xp.getGLSLProcessorKey(*gpu->glCaps().glslCaps(), &b);
|
xp.getGLSLProcessorKey(glslCaps, &b);
|
||||||
//**** use glslCaps here?
|
if (!gen_meta_key(xp, glslCaps, 0, &b)) {
|
||||||
if (!gen_meta_key(xp, gpu->glCaps(), 0, &b)) {
|
|
||||||
glDesc->key().reset();
|
glDesc->key().reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -139,6 +136,9 @@ bool GrGLProgramDescBuilder::Build(GrProgramDesc* desc,
|
|||||||
header->fFragPosKey = 0;
|
header->fFragPosKey = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header->fOutputSwizzle =
|
||||||
|
glslCaps.configOutputSwizzle(pipeline.getRenderTarget()->config()).asKey();
|
||||||
|
|
||||||
if (pipeline.ignoresCoverage()) {
|
if (pipeline.ignoresCoverage()) {
|
||||||
header->fIgnoresCoverage = 1;
|
header->fIgnoresCoverage = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,14 +52,13 @@ public:
|
|||||||
* general draw information, as well as the specific color, geometry,
|
* general draw information, as well as the specific color, geometry,
|
||||||
* and coverage stages which will be used to generate the GL Program for
|
* and coverage stages which will be used to generate the GL Program for
|
||||||
* this optstate.
|
* this optstate.
|
||||||
* @param GrGLGpu A GL Gpu, the caps and Gpu object are used to output processor specific
|
* @param GrGLSLCaps Capabilities of the GLSL backend.
|
||||||
* parts of the descriptor.
|
|
||||||
* @param GrProgramDesc The built and finalized descriptor
|
* @param GrProgramDesc The built and finalized descriptor
|
||||||
**/
|
**/
|
||||||
static bool Build(GrProgramDesc*,
|
static bool Build(GrProgramDesc*,
|
||||||
const GrPrimitiveProcessor&,
|
const GrPrimitiveProcessor&,
|
||||||
const GrPipeline&,
|
const GrPipeline&,
|
||||||
const GrGLGpu*);
|
const GrGLSLCaps&);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "GrAutoLocaleSetter.h"
|
#include "GrAutoLocaleSetter.h"
|
||||||
#include "GrCoordTransform.h"
|
#include "GrCoordTransform.h"
|
||||||
#include "GrGLProgramBuilder.h"
|
#include "GrGLProgramBuilder.h"
|
||||||
|
#include "GrSwizzle.h"
|
||||||
#include "GrTexture.h"
|
#include "GrTexture.h"
|
||||||
#include "SkRTConf.h"
|
#include "SkRTConf.h"
|
||||||
#include "SkTraceEvent.h"
|
#include "SkTraceEvent.h"
|
||||||
@ -95,6 +96,7 @@ bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
|
|||||||
inputCoverage);
|
inputCoverage);
|
||||||
this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor, *inputCoverage,
|
this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor, *inputCoverage,
|
||||||
this->pipeline().ignoresCoverage());
|
this->pipeline().ignoresCoverage());
|
||||||
|
this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,6 +264,22 @@ void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp,
|
|||||||
fFS.codeAppend("}");
|
fFS.codeAppend("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GrGLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) {
|
||||||
|
// Swizzle the fragment shader outputs if necessary.
|
||||||
|
GrSwizzle swizzle;
|
||||||
|
swizzle.setFromKey(this->desc().header().fOutputSwizzle);
|
||||||
|
if (swizzle != GrSwizzle::RGBA()) {
|
||||||
|
fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(),
|
||||||
|
fFS.getPrimaryColorOutputName(),
|
||||||
|
swizzle.c_str());
|
||||||
|
if (hasSecondaryOutput) {
|
||||||
|
fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(),
|
||||||
|
fFS.getSecondaryColorOutputName(),
|
||||||
|
swizzle.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GrGLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
|
void GrGLProgramBuilder::verify(const GrPrimitiveProcessor& gp) {
|
||||||
SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
|
SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition());
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ private:
|
|||||||
const GrGLSLExpr4& colorIn,
|
const GrGLSLExpr4& colorIn,
|
||||||
const GrGLSLExpr4& coverageIn,
|
const GrGLSLExpr4& coverageIn,
|
||||||
bool ignoresCoverage);
|
bool ignoresCoverage);
|
||||||
|
void emitFSOutputSwizzle(bool hasSecondaryOutput);
|
||||||
|
|
||||||
void verify(const GrPrimitiveProcessor&);
|
void verify(const GrPrimitiveProcessor&);
|
||||||
void verify(const GrXferProcessor&);
|
void verify(const GrXferProcessor&);
|
||||||
|
@ -108,12 +108,17 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Given a texture's config, this determines what swizzle must be appended to accesses to the
|
* Given a texture's config, this determines what swizzle must be appended to accesses to the
|
||||||
* texture in generated shader code. Swizzling may be implemented in texture parameters or a
|
* texture in generated shader code. Swizzling may be implemented in texture parameters or a
|
||||||
* sampler rather than in the shader. In this case the shader swizzle will always be "rgba".
|
* sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
|
||||||
*/
|
*/
|
||||||
const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
|
const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
|
||||||
return fConfigTextureSwizzle[config];
|
return fConfigTextureSwizzle[config];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Swizzle that should occur on the fragment shader outputs for a given config. */
|
||||||
|
const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
|
||||||
|
return fConfigOutputSwizzle[config];
|
||||||
|
}
|
||||||
|
|
||||||
GrGLSLGeneration generation() const { return fGLSLGeneration; }
|
GrGLSLGeneration generation() const { return fGLSLGeneration; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,6 +155,7 @@ private:
|
|||||||
AdvBlendEqInteraction fAdvBlendEqInteraction;
|
AdvBlendEqInteraction fAdvBlendEqInteraction;
|
||||||
|
|
||||||
GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
|
GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
|
||||||
|
GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
|
||||||
|
|
||||||
friend class GrGLCaps; // For initialization.
|
friend class GrGLCaps; // For initialization.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user