diff options
Diffstat (limited to 'src/gpu/gl')
-rw-r--r-- | src/gpu/gl/GrGLPath.cpp | 101 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.h | 43 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 21 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 13 |
5 files changed, 174 insertions, 14 deletions
diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp new file mode 100644 index 0000000000..2fceaa3209 --- /dev/null +++ b/src/gpu/gl/GrGLPath.cpp @@ -0,0 +1,101 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrGLPath.h" +#include "GrGpuGL.h" + +#define GPUGL static_cast<GrGpuGL*>(this->getGpu()) + +#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X) +#define GL_CALL_RET(R, X) GR_GL_CALL_RET(GPUGL->glInterface(), R, X) + +namespace { +inline GrGLubyte verb_to_gl_path_cmd(const SkPath::Verb verb) { + static const GrGLubyte gTable[] = { + GR_GL_MOVE_TO, + GR_GL_LINE_TO, + GR_GL_QUADRATIC_CURVE_TO, + GR_GL_CUBIC_CURVE_TO, + GR_GL_CLOSE_PATH, + }; + GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); + GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); + GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); + GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb); + GR_STATIC_ASSERT(4 == SkPath::kClose_Verb); + + GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable)); + return gTable[verb]; +} + +inline int num_pts(const SkPath::Verb verb) { + static const int gTable[] = { + 1, // move + 1, // line + 2, // quad + 3, // cubic + 0, // close + }; + GR_STATIC_ASSERT(0 == SkPath::kMove_Verb); + GR_STATIC_ASSERT(1 == SkPath::kLine_Verb); + GR_STATIC_ASSERT(2 == SkPath::kQuad_Verb); + GR_STATIC_ASSERT(3 == SkPath::kCubic_Verb); + GR_STATIC_ASSERT(4 == SkPath::kClose_Verb); + + GrAssert(verb >= 0 && verb < GR_ARRAY_COUNT(gTable)); + return gTable[verb]; +} +} + +GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path) : INHERITED(gpu) { + GL_CALL_RET(fPathID, GenPaths(1)); + SkPath::Iter iter(path, true); + + SkSTArray<16, GrGLubyte, true> pathCommands; + GR_STATIC_ASSERT(SK_SCALAR_IS_FLOAT); // assuming SkPoint is floats + SkSTArray<16, SkPoint, true> pathPoints; + + int verbCnt = path.countVerbs(); + int pointCnt = path.countPoints(); + pathCommands.resize_back(verbCnt); + pathPoints.resize_back(pointCnt); + + // TODO: Direct access to path points since we could pass them on directly. + path.getPoints(&pathPoints[0], pointCnt); + path.getVerbs(&pathCommands[0], verbCnt); + + GR_DEBUGCODE(int numPts = 0); + for (int i = 0; i < verbCnt; ++i) { + SkPath::Verb v = static_cast<SkPath::Verb>(pathCommands[i]); + pathCommands[i] = verb_to_gl_path_cmd(v); + GR_DEBUGCODE(numPts += num_pts(v)); + } + GrAssert(pathPoints.count() == numPts); + + GL_CALL(PathCommands(fPathID, + verbCnt, &pathCommands[0], + 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); + GrRect bounds = path.getBounds(); + bounds.roundOut(&fBounds); +} + +GrGLPath::~GrGLPath() { + this->release(); +} + +void GrGLPath::onRelease() { + if (0 != fPathID) { + GL_CALL(DeletePaths(1, fPathID)); + fPathID = 0; + } +} + +void GrGLPath::onAbandon() { + fPathID = 0; +} + diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h new file mode 100644 index 0000000000..f9febb46b6 --- /dev/null +++ b/src/gpu/gl/GrGLPath.h @@ -0,0 +1,43 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLPath_DEFINED +#define GrGLPath_DEFINED + +#include "../GrPath.h" +#include "gl/GrGLFunctions.h" + +class GrGpuGL; +class SkPath; + +/** + * Currently this represents a path built using GL_NV_path_rendering. If we + * support other GL path extensions then this would have to have a type enum + * and/or be subclassed. + */ + +class GrGLPath : public GrPath { +public: + GrGLPath(GrGpuGL* gpu, const SkPath& path); + virtual ~GrGLPath(); + GrGLuint pathID() const { return fPathID; } + // TODO: Figure out how to get an approximate size of the path in Gpu + // memory. + virtual size_t sizeInBytes() const SK_OVERRIDE { return 100; } + +protected: + virtual void onRelease() SK_OVERRIDE; + virtual void onAbandon() SK_OVERRIDE; + +private: + GrGLuint fPathID; + + typedef GrPath INHERITED; +}; + +#endif diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index da168cda13..77d875837b 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -8,6 +8,7 @@ #include "GrGpuGL.h" #include "GrGLStencilBuffer.h" +#include "GrGLPath.h" #include "GrTypes.h" #include "SkTemplates.h" @@ -1325,6 +1326,14 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) { return NULL; } +GrPath* GrGpuGL::onCreatePath(const SkPath& inPath) { + GrPath* path = NULL; + if (fCaps.fPathStencilingSupport) { + path = new GrGLPath(this, inPath); + } + return path; +} + void GrGpuGL::enableScissoring(const GrIRect& rect) { const GrDrawState& drawState = this->getDrawState(); const GrGLRenderTarget* rt = @@ -1718,6 +1727,10 @@ void GrGpuGL::onGpuDrawNonIndexed(GrPrimitiveType type, #endif } +void GrGpuGL::onGpuStencilPath(const GrPath&, GrPathFill) { + GrCrash("Not implemented yet. Should not get here."); +} + void GrGpuGL::onResolveRenderTarget(GrRenderTarget* target) { GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target); @@ -1955,7 +1968,7 @@ void GrGpuGL::flushStencil() { } } -void GrGpuGL::flushAAState(GrPrimitiveType type) { +void GrGpuGL::flushAAState(bool isLines) { const GrRenderTarget* rt = this->getDrawState().getRenderTarget(); if (kDesktop_GrGLBinding == this->glBinding()) { // ES doesn't support toggling GL_MULTISAMPLE and doesn't have @@ -1963,7 +1976,7 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) { // we prefer smooth lines over multisampled lines bool smoothLines = false; - if (GrIsPrimTypeLines(type)) { + if (isLines) { smoothLines = this->willUseHWAALines(); if (smoothLines) { if (kYes_TriState != fHWAAState.fSmoothLineEnabled) { @@ -1999,10 +2012,10 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) { } } -void GrGpuGL::flushBlend(GrPrimitiveType type, +void GrGpuGL::flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { - if (GrIsPrimTypeLines(type) && this->willUseHWAALines()) { + if (isLines && this->willUseHWAALines()) { if (kYes_TriState != fHWBlendState.fEnabled) { GL_CALL(Enable(GR_GL_BLEND)); fHWBlendState.fEnabled = kYes_TriState; diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 290617099d..51e49ec1ec 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -67,6 +67,7 @@ protected: bool dynamic) SK_OVERRIDE; virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size, bool dynamic) SK_OVERRIDE; + virtual GrPath* onCreatePath(const SkPath&) SK_OVERRIDE; virtual GrTexture* onCreatePlatformTexture( const GrPlatformTextureDesc& desc) SK_OVERRIDE; virtual GrRenderTarget* onCreatePlatformRenderTarget( @@ -106,13 +107,14 @@ protected: virtual void onGpuDrawNonIndexed(GrPrimitiveType type, uint32_t vertexCount, uint32_t numVertices) SK_OVERRIDE; + virtual void onGpuStencilPath(const GrPath&, GrPathFill) SK_OVERRIDE; virtual void enableScissoring(const GrIRect& rect) SK_OVERRIDE; virtual void disableScissor() SK_OVERRIDE; virtual void clearStencil() SK_OVERRIDE; virtual void clearStencilClip(const GrIRect& rect, bool insideClip) SK_OVERRIDE; - virtual bool flushGraphicsState(GrPrimitiveType type) SK_OVERRIDE; + virtual bool flushGraphicsState(DrawType) SK_OVERRIDE; virtual void setupGeometry(int* startVertex, int* startIndex, int vertexCount, @@ -135,7 +137,7 @@ private: // The params should be the final coeffecients to apply // (after any blending optimizations or dual source blending considerations // have been accounted for). - void flushBlend(GrPrimitiveType type, + void flushBlend(bool isLines, GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff); @@ -233,7 +235,7 @@ private: static void DeleteProgram(const GrGLInterface* gl, CachedData* programData); - void buildProgram(GrPrimitiveType typeBlend, + void buildProgram(bool isPoints, BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, GrCustomStage** customStages); @@ -261,7 +263,7 @@ private: // NULL means whole target. Can be an empty rect. void flushRenderTarget(const GrIRect* bound); void flushStencil(); - void flushAAState(GrPrimitiveType type); + void flushAAState(bool isLines); bool configToGLFormats(GrPixelConfig config, bool getSizedInternal, diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index a38ae2dc98..97f9b6d817 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -370,7 +370,7 @@ void GrGpuGL::flushCoverage(GrColor coverage) { } } -bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) { +bool GrGpuGL::flushGraphicsState(DrawType type) { const GrDrawState& drawState = this->getDrawState(); // GrGpu::setupClipAndFlushState should have already checked this @@ -379,7 +379,7 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) { this->flushMiscFixedFunctionState(); this->flushStencil(); - this->flushAAState(type); + this->flushAAState(kDrawLines_DrawType == type); GrBlendCoeff srcCoeff; GrBlendCoeff dstCoeff; @@ -389,7 +389,8 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) { } GrCustomStage* customStages [GrDrawState::kNumStages]; - this->buildProgram(type, blendOpts, dstCoeff, customStages); + this->buildProgram(kDrawPoints_DrawType == type, + blendOpts, dstCoeff, customStages); fProgramData = fProgramCache->getProgramData(fCurrentProgram, customStages); if (NULL == fProgramData) { @@ -402,7 +403,7 @@ bool GrGpuGL::flushGraphicsState(GrPrimitiveType type) { fHWProgramID = fProgramData->fProgramID; } fCurrentProgram.overrideBlend(&srcCoeff, &dstCoeff); - this->flushBlend(type, srcCoeff, dstCoeff); + this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff); GrColor color; GrColor coverage; @@ -635,7 +636,7 @@ void setup_custom_stage(GrGLProgram::ProgramDesc::StageDesc* stage, } -void GrGpuGL::buildProgram(GrPrimitiveType type, +void GrGpuGL::buildProgram(bool isPoints, BlendOptFlags blendOpts, GrBlendCoeff dstCoeff, GrCustomStage** customStages) { @@ -658,7 +659,7 @@ void GrGpuGL::buildProgram(GrPrimitiveType type, // Must initialize all fields or cache will have false negatives! desc.fVertexLayout = this->getVertexLayout(); - desc.fEmitsPointSize = kPoints_GrPrimitiveType == type; + desc.fEmitsPointSize = isPoints; bool requiresAttributeColors = !skipColor && SkToBool(desc.fVertexLayout & kColor_VertexLayoutBit); |