From 651713408c5a5d9565665967ad09981250c7a8c9 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Thu, 9 Oct 2014 07:25:36 -0700 Subject: gl programs rewrite BUG=skia: Committed: https://skia.googlesource.com/skia/+/07a255310aca9f3e83bf741dc663a58818ad681c Review URL: https://codereview.chromium.org/628633003 --- src/effects/SkColorFilters.cpp | 8 ++- src/gpu/GrDrawState.cpp | 7 +- src/gpu/GrDrawState.h | 5 +- src/gpu/GrDrawTarget.h | 15 +++-- src/gpu/gl/GrGLProgramDesc.cpp | 150 ++++++++++++++++++++++------------------- src/gpu/gl/GrGLProgramDesc.h | 45 ++----------- src/gpu/gl/GrGpuGL_program.cpp | 18 ++--- 7 files changed, 117 insertions(+), 131 deletions(-) (limited to 'src') diff --git a/src/effects/SkColorFilters.cpp b/src/effects/SkColorFilters.cpp index ba62817f56..8e10d73a0e 100644 --- a/src/effects/SkColorFilters.cpp +++ b/src/effects/SkColorFilters.cpp @@ -406,7 +406,13 @@ GrFragmentProcessor* ModeColorFilterEffect::TestCreate(SkRandom* rand, while (SkXfermode::kDst_Mode == mode) { mode = static_cast(rand->nextRangeU(0, SkXfermode::kLastCoeffMode)); } - GrColor color = rand->nextU(); + + // pick a random premul color + uint8_t alpha = rand->nextULessThan(256); + GrColor color = GrColorPackRGBA(rand->nextRangeU(0, alpha), + rand->nextRangeU(0, alpha), + rand->nextRangeU(0, alpha), + alpha); return ModeColorFilterEffect::Create(color, mode); } diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 6831fad1f9..5e177b8b12 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -404,7 +404,7 @@ bool GrDrawState::hasSolidCoverage() const { if (this->hasCoverageVertexAttribute()) { inout.fValidFlags = 0; } else { - inout.fColor = fCoverage; + inout.fColor = this->getCoverageColor(); inout.fValidFlags = kRGBA_GrColorComponentFlags; } @@ -413,6 +413,7 @@ bool GrDrawState::hasSolidCoverage() const { const GrGeometryProcessor* gp = fGeometryProcessor->getProcessor(); gp->computeInvariantOutput(&inout); } + for (int s = 0; s < this->numCoverageStages(); ++s) { const GrProcessor* processor = this->getCoverageStage(s).getProcessor(); processor->computeInvariantOutput(&inout); @@ -640,8 +641,8 @@ GrDrawState::~GrDrawState() { //////////////////////////////////////////////////////////////////////////////// GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, - GrBlendCoeff* srcCoeff, - GrBlendCoeff* dstCoeff) const { + GrBlendCoeff* srcCoeff, + GrBlendCoeff* dstCoeff) const { GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; if (NULL == srcCoeff) { srcCoeff = &bogusSrcCoeff; diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 5575b12966..03af7b532f 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -684,7 +684,10 @@ public: /// Hints that when provided can enable optimizations. //// - enum Hints { kVertexColorsAreOpaque_Hint = 0x1, }; + enum Hints { + kVertexColorsAreOpaque_Hint = 0x1, + kLast_Hint = kVertexColorsAreOpaque_Hint + }; void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index dd2224bdbd..552314bca3 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -855,6 +855,14 @@ protected: GrDeviceCoordTexture fDstCopy; }; + // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required + // but couldn't be made. Otherwise, returns true. This method needs to be protected because it + // needs to be accessed by GLPrograms to setup a correct drawstate + bool setupDstReadIfNecessary(DrawInfo* info) { + return this->setupDstReadIfNecessary(&info->fDstCopy, info->getDevBounds()); + } + bool setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); + private: // A subclass can optionally overload this function to be notified before // vertex and index space is reserved. @@ -913,13 +921,6 @@ private: void releasePreviousVertexSource(); void releasePreviousIndexSource(); - // Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required - // but couldn't be made. Otherwise, returns true. - bool setupDstReadIfNecessary(DrawInfo* info) { - return this->setupDstReadIfNecessary(&info->fDstCopy, info->getDevBounds()); - } - bool setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); - // Check to see if this set of draw commands has been sent out virtual bool isIssued(uint32_t drawID) { return true; } diff --git a/src/gpu/gl/GrGLProgramDesc.cpp b/src/gpu/gl/GrGLProgramDesc.cpp index ec09527182..0c85c99a8a 100644 --- a/src/gpu/gl/GrGLProgramDesc.cpp +++ b/src/gpu/gl/GrGLProgramDesc.cpp @@ -140,11 +140,11 @@ static uint32_t* get_processor_meta_key(const GrProcessorStage& processorStage, return key; } -bool GrGLProgramDesc::GetProcessorKey(const GrProcessorStage& stage, - const GrGLCaps& caps, - bool useExplicitLocalCoords, - GrProcessorKeyBuilder* b, - uint16_t* processorKeySize) { +static bool get_fp_key(const GrProcessorStage& stage, + const GrGLCaps& caps, + bool useExplicitLocalCoords, + GrProcessorKeyBuilder* b, + uint16_t* processorKeySize) { const GrProcessor& effect = *stage.getProcessor(); const GrBackendProcessorFactory& factory = effect.getFactory(); factory.getGLProcessorKey(effect, caps, b); @@ -160,11 +160,11 @@ bool GrGLProgramDesc::GetProcessorKey(const GrProcessorStage& stage, return true; } -bool GrGLProgramDesc::GetGeometryProcessorKey(const GrGeometryStage& stage, - const GrGLCaps& caps, - bool useExplicitLocalCoords, - GrProcessorKeyBuilder* b, - uint16_t* processorKeySize) { +static bool get_gp_key(const GrGeometryStage& stage, + const GrGLCaps& caps, + bool useExplicitLocalCoords, + GrProcessorKeyBuilder* b, + uint16_t* processorKeySize) { const GrProcessor& effect = *stage.getProcessor(); const GrBackendProcessorFactory& factory = effect.getFactory(); factory.getGLProcessorKey(effect, caps, b); @@ -191,6 +191,54 @@ bool GrGLProgramDesc::GetGeometryProcessorKey(const GrGeometryStage& stage, return true; } +struct GeometryProcessorKeyBuilder { + typedef GrGeometryStage StagedProcessor; + static bool GetProcessorKey(const GrGeometryStage& gpStage, + const GrGLCaps& caps, + bool requiresLocalCoordAttrib, + GrProcessorKeyBuilder* b, + uint16_t* processorKeySize) { + return get_gp_key(gpStage, caps, requiresLocalCoordAttrib, b, processorKeySize); + } +}; + +struct FragmentProcessorKeyBuilder { + typedef GrFragmentStage StagedProcessor; + static bool GetProcessorKey(const GrFragmentStage& fpStage, + const GrGLCaps& caps, + bool requiresLocalCoordAttrib, + GrProcessorKeyBuilder* b, + uint16_t* processorKeySize) { + return get_fp_key(fpStage, caps, requiresLocalCoordAttrib, b, processorKeySize); + } +}; + + +template +bool +GrGLProgramDesc::BuildStagedProcessorKey(const typename ProcessorKeyBuilder::StagedProcessor& stage, + const GrGLCaps& caps, + bool requiresLocalCoordAttrib, + GrGLProgramDesc* desc, + int* offsetAndSizeIndex) { + GrProcessorKeyBuilder b(&desc->fKey); + uint16_t processorKeySize; + uint32_t processorOffset = desc->fKey.count(); + if (processorOffset > SK_MaxU16 || + !ProcessorKeyBuilder::GetProcessorKey(stage, caps, requiresLocalCoordAttrib, &b, + &processorKeySize)){ + desc->fKey.reset(); + return false; + } + + uint16_t* offsetAndSize = + reinterpret_cast(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + + *offsetAndSizeIndex * 2 * sizeof(uint16_t)); + offsetAndSize[0] = SkToU16(processorOffset); + offsetAndSize[1] = processorKeySize; + ++(*offsetAndSizeIndex); + return true; +} bool GrGLProgramDesc::Build(const GrOptDrawState& optState, GrGpu::DrawType drawType, @@ -224,90 +272,51 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, int offsetAndSizeIndex = 0; - KeyHeader* header = desc->header(); - // make sure any padding in the header is zeroed. - memset(desc->header(), 0, kHeaderSize); - // We can only have one effect which touches the vertex shader if (optState.hasGeometryProcessor()) { - uint16_t* offsetAndSize = - reinterpret_cast(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + - offsetAndSizeIndex * 2 * sizeof(uint16_t)); - - GrProcessorKeyBuilder b(&desc->fKey); - uint16_t processorKeySize; - uint32_t processorOffset = desc->fKey.count(); const GrGeometryStage& gpStage = *optState.getGeometryProcessor(); - if (processorOffset > SK_MaxU16 || - !GetGeometryProcessorKey(gpStage, gpu->glCaps(), requiresLocalCoordAttrib, &b, - &processorKeySize)) { - desc->fKey.reset(); + if (!BuildStagedProcessorKey(gpStage, + gpu->glCaps(), + requiresLocalCoordAttrib, + desc, + &offsetAndSizeIndex)) { return false; } - - offsetAndSize[0] = SkToU16(processorOffset); - offsetAndSize[1] = processorKeySize; - ++offsetAndSizeIndex; *geometryProcessor = &gpStage; - header->fHasGeometryProcessor = true; } for (int s = 0; s < optState.numColorStages(); ++s) { - uint16_t* offsetAndSize = - reinterpret_cast(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + - offsetAndSizeIndex * 2 * sizeof(uint16_t)); - - GrProcessorKeyBuilder b(&desc->fKey); - uint16_t processorKeySize; - uint32_t processorOffset = desc->fKey.count(); - if (processorOffset > SK_MaxU16 || - !GetProcessorKey(optState.getColorStage(s), gpu->glCaps(), - requiresLocalCoordAttrib, &b, &processorKeySize)) { - desc->fKey.reset(); + if (!BuildStagedProcessorKey(optState.getColorStage(s), + gpu->glCaps(), + requiresLocalCoordAttrib, + desc, + &offsetAndSizeIndex)) { return false; } - - offsetAndSize[0] = SkToU16(processorOffset); - offsetAndSize[1] = processorKeySize; - ++offsetAndSizeIndex; } for (int s = 0; s < optState.numCoverageStages(); ++s) { - uint16_t* offsetAndSize = - reinterpret_cast(desc->fKey.begin() + kEffectKeyOffsetsAndLengthOffset + - offsetAndSizeIndex * 2 * sizeof(uint16_t)); - - GrProcessorKeyBuilder b(&desc->fKey); - uint16_t processorKeySize; - uint32_t processorOffset = desc->fKey.count(); - if (processorOffset > SK_MaxU16 || - !GetProcessorKey(optState.getCoverageStage(s), gpu->glCaps(), - requiresLocalCoordAttrib, &b, &processorKeySize)) { - desc->fKey.reset(); + if (!BuildStagedProcessorKey(optState.getCoverageStage(s), + gpu->glCaps(), + requiresLocalCoordAttrib, + desc, + &offsetAndSizeIndex)) { return false; } - - offsetAndSize[0] = SkToU16(processorOffset); - offsetAndSize[1] = processorKeySize; - ++offsetAndSizeIndex; } + // --------DO NOT MOVE HEADER ABOVE THIS LINE-------------------------------------------------- // Because header is a pointer into the dynamic array, we can't push any new data into the key // below here. + KeyHeader* header = desc->header(); + + // make sure any padding in the header is zeroed. + memset(header, 0, kHeaderSize); + header->fHasGeometryProcessor = optState.hasGeometryProcessor(); header->fEmitsPointSize = GrGpu::kDrawPoints_DrawType == drawType; - // Currently the experimental GS will only work with triangle prims (and it doesn't do anything - // other than pass through values from the VS to the FS anyway). -#if GR_GL_EXPERIMENTAL_GS -#if 0 - header->fExperimentalGS = gpu->caps().geometryShaderSupport(); -#else - header->fExperimentalGS = false; -#endif -#endif - if (gpu->caps()->pathRenderingSupport() && GrGpu::IsPathRenderingDrawType(drawType) && gpu->glPathRendering()->texturingMode() == GrGLPathRendering::FixedFunction_TexturingMode) { @@ -399,7 +408,6 @@ bool GrGLProgramDesc::Build(const GrOptDrawState& optState, header->fColorEffectCnt = colorStages->count(); header->fCoverageEffectCnt = coverageStages->count(); - desc->finalize(); return true; } diff --git a/src/gpu/gl/GrGLProgramDesc.h b/src/gpu/gl/GrGLProgramDesc.h index faa59f329f..9bf7553b61 100644 --- a/src/gpu/gl/GrGLProgramDesc.h +++ b/src/gpu/gl/GrGLProgramDesc.h @@ -15,15 +15,6 @@ class GrGpuGL; -#ifdef SK_DEBUG - // Optionally compile the experimental GS code. Set to SK_DEBUG so that debug build bots will - // execute the code. - #define GR_GL_EXPERIMENTAL_GS 1 -#else - #define GR_GL_EXPERIMENTAL_GS 0 -#endif - - /** This class describes a program to generate. It also serves as a program cache key. Very little of this is GL-specific. The GL-specific parts could be factored out into a subclass. */ class GrGLProgramDesc { @@ -44,18 +35,6 @@ public: // Gets the a checksum of the key. Can be used as a hash value for a fast lookup in a cache. uint32_t getChecksum() const { return *this->atOffset(); } - // For unit testing. - bool setRandom(SkRandom*, - GrGpuGL*, - const GrRenderTarget* dummyDstRenderTarget, - const GrTexture* dummyDstCopyTexture, - const GrGeometryStage* geometryProcessor, - const GrFragmentStage* stages[], - int numColorStages, - int numCoverageStages, - int currAttribIndex, - GrGpu::DrawType); - /** * Builds a program descriptor from a GrOptDrawState. Whether the primitive type is points, and * the caps of the GrGpuGL are also inputs. It also outputs the color and coverage stages @@ -129,13 +108,6 @@ private: GrOptDrawState::PrimaryOutputType fPrimaryOutputType : 8; GrOptDrawState::SecondaryOutputType fSecondaryOutputType : 8; - - // To enable experimental geometry shader code (not for use in - // production) -#if GR_GL_EXPERIMENTAL_GS - SkBool8 fExperimentalGS; -#endif - int8_t fPositionAttributeIndex; int8_t fLocalCoordAttributeIndex; int8_t fColorAttributeIndex; @@ -176,18 +148,13 @@ private: KeyHeader* header() { return this->atOffset(); } - // Shared code between setRandom() and Build(). - static bool GetProcessorKey(const GrProcessorStage& stage, - const GrGLCaps& caps, - bool useExplicitLocalCoords, - GrProcessorKeyBuilder* b, - uint16_t* effectKeySize); - - static bool GetGeometryProcessorKey(const GrGeometryStage& stage, + // a helper class to handle getting an individual processor's key + template + static bool BuildStagedProcessorKey(const typename ProcessorKeyBuilder::StagedProcessor& stage, const GrGLCaps& caps, - bool useExplicitLocalCoords, - GrProcessorKeyBuilder* b, - uint16_t* effectKeySize); + bool requiresLocalCoordAttrib, + GrGLProgramDesc* desc, + int* offsetAndSizeIndex); void finalize(); const KeyHeader& getHeader() const { return *this->atOffset(); } diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 891b49a1f8..7dba5316a4 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -242,15 +242,15 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC SkSTArray<8, const GrFragmentStage*, true> coverageStages; GrGLProgramDesc desc; if (!GrGLProgramDesc::Build(*optState.get(), - type, - srcCoeff, - dstCoeff, - this, - dstCopy, - &geometryProcessor, - &colorStages, - &coverageStages, - &desc)) { + type, + srcCoeff, + dstCoeff, + this, + dstCopy, + &geometryProcessor, + &colorStages, + &coverageStages, + &desc)) { SkDEBUGFAIL("Failed to generate GL program descriptor"); return false; } -- cgit v1.2.3