diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/gl/GrGLAssembleInterface.cpp | 113 | ||||
-rw-r--r-- | src/gpu/gl/GrGLInterface.cpp | 29 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.cpp | 34 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPath.h | 3 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRange.cpp | 21 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRange.h | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRendering.cpp | 281 | ||||
-rw-r--r-- | src/gpu/gl/GrGLPathRendering.h | 108 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.cpp | 108 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL.h | 14 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGL_program.cpp | 4 |
11 files changed, 480 insertions, 237 deletions
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp index 4ae50ba391..8fd173d9f4 100644 --- a/src/gpu/gl/GrGLAssembleInterface.cpp +++ b/src/gpu/gl/GrGLAssembleInterface.cpp @@ -14,12 +14,6 @@ #define GET_PROC_SUFFIX(F, S) functions->f ## F = (GrGL ## F ## Proc) get(ctx, "gl" #F #S) #define GET_PROC_LOCAL(F) GrGL ## F ## Proc F = (GrGL ## F ## Proc) get(ctx, "gl" #F) -// The glStencilThenCover* methods are a new addition to NV_path_rendering. They -// aren't available on all drivers. In the event that they are not present, this -// function can be used to add methods to the given GrGLInterface that emulate -// them using the existing glStencil*/glCover* methods. -static void emulate_nvpr_stencil_then_cover(GrGLInterface*); - const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) { GET_PROC_LOCAL(GetString); GET_PROC_LOCAL(GetStringi); @@ -245,18 +239,13 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) { GET_PROC_SUFFIX(CoverStrokePath, NV); GET_PROC_SUFFIX(CoverFillPathInstanced, NV); GET_PROC_SUFFIX(CoverStrokePathInstanced, NV); + // NV_path_rendering v1.2 (These methods may not be present) GET_PROC_SUFFIX(StencilThenCoverFillPath, NV); GET_PROC_SUFFIX(StencilThenCoverStrokePath, NV); GET_PROC_SUFFIX(StencilThenCoverFillPathInstanced, NV); GET_PROC_SUFFIX(StencilThenCoverStrokePathInstanced, NV); + // NV_path_rendering v1.3 (These methods may not be present) GET_PROC_SUFFIX(ProgramPathFragmentInputGen, NV); - - if (NULL == interface->fFunctions.fStencilThenCoverFillPath || - NULL == interface->fFunctions.fStencilThenCoverStrokePath || - NULL == interface->fFunctions.fStencilThenCoverFillPathInstanced || - NULL == interface->fFunctions.fStencilThenCoverFillPathInstanced) { - emulate_nvpr_stencil_then_cover(interface); - } } if (extensions.has("GL_EXT_debug_marker")) { @@ -283,101 +272,3 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) { return interface; } - -static GrGLStencilFillPathProc gStencilFillPath; -static GrGLCoverFillPathProc gCoverFillPath; -static GrGLvoid GR_GL_FUNCTION_TYPE stencil_then_cover_fill_path( - GrGLuint path, GrGLenum fillMode, - GrGLuint mask, GrGLenum coverMode) { - gStencilFillPath(path, fillMode, mask); - gCoverFillPath(path, coverMode); -} - - -static GrGLStencilStrokePathProc gStencilStrokePath; -static GrGLCoverStrokePathProc gCoverStrokePath; -static GrGLvoid GR_GL_FUNCTION_TYPE stencil_then_cover_stroke_path( - GrGLuint path, GrGLint reference, - GrGLuint mask, GrGLenum coverMode) { - gStencilStrokePath(path, reference, mask); - gCoverStrokePath(path, coverMode); -} - -static GrGLStencilFillPathInstancedProc gStencilFillPathInstanced; -static GrGLCoverFillPathInstancedProc gCoverFillPathInstanced; -static GrGLvoid GR_GL_FUNCTION_TYPE stencil_then_cover_fill_path_instanced( - GrGLsizei numPaths, GrGLenum pathNameType, - const GrGLvoid *paths, GrGLuint pathBase, - GrGLenum fillMode, GrGLuint mask, - GrGLenum coverMode, GrGLenum transformType, - const GrGLfloat *transformValues) { - gStencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, - fillMode, mask, transformType, transformValues); - gCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, - coverMode, transformType, transformValues); -} - -static GrGLStencilStrokePathInstancedProc gStencilStrokePathInstanced; -static GrGLCoverStrokePathInstancedProc gCoverStrokePathInstanced; -static GrGLvoid GR_GL_FUNCTION_TYPE stencil_then_cover_stroke_path_instanced( - GrGLsizei numPaths, GrGLenum pathNameType, - const GrGLvoid *paths, GrGLuint pathBase, - GrGLint reference, GrGLuint mask, - GrGLenum coverMode, GrGLenum transformType, - const GrGLfloat *transformValues) { - gStencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, - reference, mask, transformType, transformValues); - gCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, - coverMode, transformType, transformValues); -} - -static void emulate_nvpr_stencil_then_cover(GrGLInterface* interface) { - if (NULL == gStencilFillPath) { - gStencilFillPath = (GrGLStencilFillPathProc)interface->fFunctions.fStencilFillPath; - } - if (NULL == gCoverFillPath) { - gCoverFillPath = (GrGLCoverFillPathProc)interface->fFunctions.fCoverFillPath; - } - if (NULL == gStencilStrokePath) { - gStencilStrokePath = (GrGLStencilStrokePathProc)interface->fFunctions.fStencilStrokePath; - } - if (NULL == gCoverStrokePath) { - gCoverStrokePath = (GrGLCoverStrokePathProc)interface->fFunctions.fCoverStrokePath; - } - if (NULL == gStencilFillPathInstanced) { - gStencilFillPathInstanced = (GrGLStencilFillPathInstancedProc) - interface->fFunctions.fStencilFillPathInstanced; - } - if (NULL == gCoverFillPathInstanced) { - gCoverFillPathInstanced = (GrGLCoverFillPathInstancedProc) - interface->fFunctions.fCoverFillPathInstanced; - } - if (NULL == gStencilStrokePathInstanced) { - gStencilStrokePathInstanced = (GrGLStencilStrokePathInstancedProc) - interface->fFunctions.fStencilStrokePathInstanced; - } - if (NULL == gCoverStrokePathInstanced) { - gCoverStrokePathInstanced = (GrGLCoverStrokePathInstancedProc) - interface->fFunctions.fCoverStrokePathInstanced; - } - - if (interface->fFunctions.fStencilFillPath != gStencilFillPath || - interface->fFunctions.fCoverFillPath != gCoverFillPath || - interface->fFunctions.fStencilStrokePath != gStencilStrokePath || - interface->fFunctions.fCoverStrokePath != gCoverStrokePath || - interface->fFunctions.fStencilFillPathInstanced != gStencilFillPathInstanced || - interface->fFunctions.fCoverFillPathInstanced != gCoverFillPathInstanced || - interface->fFunctions.fStencilStrokePathInstanced != gStencilStrokePathInstanced || - interface->fFunctions.fCoverStrokePathInstanced != gCoverStrokePathInstanced) { - // While not every windowing system requires GetProcAddress to return - // the same addresses in different contexts, it is guaranteed to do so - // in any context that supports NV_path_rendering. - SkFAIL("GetProcAddress returned different addresses for the same nvpr functions"); - return; - } - - interface->fFunctions.fStencilThenCoverFillPath = &stencil_then_cover_fill_path; - interface->fFunctions.fStencilThenCoverStrokePath = &stencil_then_cover_stroke_path; - interface->fFunctions.fStencilThenCoverFillPathInstanced = &stencil_then_cover_fill_path_instanced; - interface->fFunctions.fStencilThenCoverStrokePathInstanced = &stencil_then_cover_stroke_path_instanced; -} diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp index e9ba32ed24..c192611f50 100644 --- a/src/gpu/gl/GrGLInterface.cpp +++ b/src/gpu/gl/GrGLInterface.cpp @@ -56,6 +56,10 @@ const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) { newInterface->fFunctions.fCoverStrokePath = NULL; newInterface->fFunctions.fCoverFillPathInstanced = NULL; newInterface->fFunctions.fCoverStrokePathInstanced = NULL; + newInterface->fFunctions.fStencilThenCoverFillPath = NULL; + newInterface->fFunctions.fStencilThenCoverStrokePath = NULL; + newInterface->fFunctions.fStencilThenCoverFillPathInstanced = NULL; + newInterface->fFunctions.fStencilThenCoverStrokePathInstanced = NULL; newInterface->fFunctions.fProgramPathFragmentInputGen = NULL; return newInterface; } @@ -467,18 +471,23 @@ bool GrGLInterface::validate() const { NULL == fFunctions.fCoverFillPath || NULL == fFunctions.fCoverStrokePath || NULL == fFunctions.fCoverFillPathInstanced || - NULL == fFunctions.fCoverStrokePathInstanced || - NULL == fFunctions.fStencilThenCoverFillPath || - NULL == fFunctions.fStencilThenCoverStrokePath || - NULL == fFunctions.fStencilThenCoverFillPathInstanced || - NULL == fFunctions.fStencilThenCoverStrokePathInstanced) { + NULL == fFunctions.fCoverStrokePathInstanced) { RETURN_FALSE_INTERFACE } - // Currently ProgramPathFragmentInputGen is not used on - // OpenGL, rather PathTexGen is. - if ((kGL_GrGLStandard == fStandard && NULL == fFunctions.fPathTexGen) || - (kGLES_GrGLStandard == fStandard && NULL == fFunctions.fProgramPathFragmentInputGen)) { - RETURN_FALSE_INTERFACE + if (kGL_GrGLStandard == fStandard) { + // Some methods only exist on desktop + if (NULL == fFunctions.fPathTexGen) { + RETURN_FALSE_INTERFACE + } + } else { + // All additions through v1.3 exist on GLES + if (NULL == fFunctions.fStencilThenCoverFillPath || + NULL == fFunctions.fStencilThenCoverStrokePath || + NULL == fFunctions.fStencilThenCoverFillPathInstanced || + NULL == fFunctions.fStencilThenCoverStrokePathInstanced || + NULL == fFunctions.fProgramPathFragmentInputGen) { + RETURN_FALSE_INTERFACE + } } } diff --git a/src/gpu/gl/GrGLPath.cpp b/src/gpu/gl/GrGLPath.cpp index 1c745808e9..6f158cdea9 100644 --- a/src/gpu/gl/GrGLPath.cpp +++ b/src/gpu/gl/GrGLPath.cpp @@ -7,13 +7,9 @@ */ #include "GrGLPath.h" +#include "GrGLPathRendering.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(SkPath::Verb verb) { static const GrGLubyte gTable[] = { @@ -85,10 +81,11 @@ inline GrGLenum cap_to_gl_cap(SkPaint::Cap cap) { static const bool kIsWrapped = false; // The constructor creates the GL path object. -void GrGLPath::InitPathObject(const GrGLInterface* gl, +void GrGLPath::InitPathObject(GrGpuGL* gpu, GrGLuint pathID, const SkPath& skPath, const SkStrokeRec& stroke) { + GrGLPathRendering* pr = gpu->pathRendering(); SkSTArray<16, GrGLubyte, true> pathCommands; SkSTArray<16, SkPoint, true> pathPoints; @@ -109,30 +106,25 @@ void GrGLPath::InitPathObject(const GrGLInterface* gl, } SkASSERT(pathPoints.count() == numPts); - GR_GL_CALL(gl, PathCommands(pathID, - verbCnt, &pathCommands[0], - 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0])); - + pr->pathCommands(pathID, verbCnt, &pathCommands[0], 2 * pointCnt, GR_GL_FLOAT, &pathPoints[0]); if (stroke.needToApply()) { SkASSERT(!stroke.isHairlineStyle()); - GR_GL_CALL(gl, PathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth()))); - GR_GL_CALL(gl, PathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter()))); + pr->pathParameterf(pathID, GR_GL_PATH_STROKE_WIDTH, SkScalarToFloat(stroke.getWidth())); + pr->pathParameterf(pathID, GR_GL_PATH_MITER_LIMIT, SkScalarToFloat(stroke.getMiter())); GrGLenum join = join_to_gl_join(stroke.getJoin()); - GR_GL_CALL(gl, PathParameteri(pathID, GR_GL_PATH_JOIN_STYLE, join)); + pr->pathParameteri(pathID, GR_GL_PATH_JOIN_STYLE, join); GrGLenum cap = cap_to_gl_cap(stroke.getCap()); - GR_GL_CALL(gl, PathParameteri(pathID, GR_GL_PATH_INITIAL_END_CAP, cap)); - GR_GL_CALL(gl, PathParameteri(pathID, GR_GL_PATH_TERMINAL_END_CAP, cap)); + pr->pathParameteri(pathID, GR_GL_PATH_INITIAL_END_CAP, cap); + pr->pathParameteri(pathID, GR_GL_PATH_TERMINAL_END_CAP, cap); } } GrGLPath::GrGLPath(GrGpuGL* gpu, const SkPath& path, const SkStrokeRec& stroke) - : INHERITED(gpu, kIsWrapped, path, stroke) { + : INHERITED(gpu, kIsWrapped, path, stroke), + fPathID(gpu->pathRendering()->genPaths(1)) { SkASSERT(!path.isEmpty()); - fPathID = gpu->createGLPathObject(); - - InitPathObject(static_cast<GrGpuGL*>(this->getGpu())->glInterface(), - fPathID, fSkPath, stroke); + InitPathObject(gpu, fPathID, fSkPath, stroke); if (stroke.needToApply()) { // FIXME: try to account for stroking, without rasterizing the stroke. @@ -146,7 +138,7 @@ GrGLPath::~GrGLPath() { void GrGLPath::onRelease() { if (0 != fPathID && !this->isWrapped()) { - static_cast<GrGpuGL*>(this->getGpu())->deleteGLPathObject(fPathID); + static_cast<GrGpuGL*>(this->getGpu())->pathRendering()->deletePaths(fPathID, 1); fPathID = 0; } diff --git a/src/gpu/gl/GrGLPath.h b/src/gpu/gl/GrGLPath.h index 4831b7250f..935a2e24ad 100644 --- a/src/gpu/gl/GrGLPath.h +++ b/src/gpu/gl/GrGLPath.h @@ -13,7 +13,6 @@ #include "gl/GrGLFunctions.h" class GrGpuGL; -struct GrGLInterface; /** * Currently this represents a path built using GL_NV_path_rendering. If we @@ -23,7 +22,7 @@ struct GrGLInterface; class GrGLPath : public GrPath { public: - static void InitPathObject(const GrGLInterface*, + static void InitPathObject(GrGpuGL*, GrGLuint pathID, const SkPath&, const SkStrokeRec&); diff --git a/src/gpu/gl/GrGLPathRange.cpp b/src/gpu/gl/GrGLPathRange.cpp index 2df04e3057..5e89cb5d87 100644 --- a/src/gpu/gl/GrGLPathRange.cpp +++ b/src/gpu/gl/GrGLPathRange.cpp @@ -8,17 +8,13 @@ #include "GrGLPathRange.h" #include "GrGLPath.h" +#include "GrGLPathRendering.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) - -GrGLPathRange::GrGLPathRange(GrGpu* gpu, size_t size, const SkStrokeRec& stroke) +GrGLPathRange::GrGLPathRange(GrGpuGL* gpu, size_t size, const SkStrokeRec& stroke) : INHERITED(gpu, size, stroke), + fBasePathID(gpu->pathRendering()->genPaths(fSize)), fNumDefinedPaths(0) { - GL_CALL_RET(fBasePathID, GenPaths(fSize)); } GrGLPathRange::~GrGLPathRange() { @@ -31,15 +27,10 @@ void GrGLPathRange::initAt(size_t index, const SkPath& skPath) { return; } -#ifdef SK_DEBUG // Make sure the path at this index hasn't been initted already. - GrGLboolean hasPathAtIndex; - GL_CALL_RET(hasPathAtIndex, IsPath(fBasePathID + index)); - SkASSERT(GR_GL_FALSE == hasPathAtIndex); -#endif - - GrGLPath::InitPathObject(gpu->glInterface(), fBasePathID + index, skPath, fStroke); + SkASSERT(GR_GL_FALSE == gpu->pathRendering()->isPath(fBasePathID + index)); + GrGLPath::InitPathObject(gpu, fBasePathID + index, skPath, fStroke); ++fNumDefinedPaths; this->didChangeGpuMemorySize(); } @@ -48,7 +39,7 @@ void GrGLPathRange::onRelease() { SkASSERT(NULL != this->getGpu()); if (0 != fBasePathID && !this->isWrapped()) { - GL_CALL(DeletePaths(fBasePathID, fSize)); + static_cast<GrGpuGL*>(this->getGpu())->pathRendering()->deletePaths(fBasePathID, fSize); fBasePathID = 0; } diff --git a/src/gpu/gl/GrGLPathRange.h b/src/gpu/gl/GrGLPathRange.h index 6c6b78e016..927310d651 100644 --- a/src/gpu/gl/GrGLPathRange.h +++ b/src/gpu/gl/GrGLPathRange.h @@ -22,7 +22,7 @@ class GrGpuGL; class GrGLPathRange : public GrPathRange { public: - GrGLPathRange(GrGpu*, size_t size, const SkStrokeRec&); + GrGLPathRange(GrGpuGL*, size_t size, const SkStrokeRec&); virtual ~GrGLPathRange(); GrGLuint basePathID() const { return fBasePathID; } diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp new file mode 100644 index 0000000000..249d98139a --- /dev/null +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -0,0 +1,281 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "gl/GrGLPathRendering.h" +#include "gl/GrGLInterface.h" +#include "gl/GrGLNameAllocator.h" +#include "gl/GrGLUtil.h" + +#define GL_CALL(X) GR_GL_CALL(fGLInterface.get(), X) +#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGLInterface.get(), RET, X) + +class GrGLPathRenderingV12 : public GrGLPathRendering { +public: + GrGLPathRenderingV12(const GrGLInterface* glInterface) + : GrGLPathRendering(glInterface) { + } + + virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, + GrGLuint mask, GrGLenum coverMode) SK_OVERRIDE; + virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference, + GrGLuint mask, GrGLenum coverMode) SK_OVERRIDE; + virtual GrGLvoid stencilThenCoverFillPathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues) SK_OVERRIDE; + virtual GrGLvoid stencilThenCoverStrokePathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues) SK_OVERRIDE; +}; + +class GrGLPathRenderingV13 : public GrGLPathRenderingV12 { +public: + GrGLPathRenderingV13(const GrGLInterface* glInterface) + : GrGLPathRenderingV12(glInterface) { + fCaps.fragmentInputGenSupport = true; + } + + virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint location, + GrGLenum genMode, GrGLint components, + const GrGLfloat *coeffs) SK_OVERRIDE; +}; + + +GrGLPathRendering* GrGLPathRendering::Create(const GrGLInterface* glInterface) { + if (NULL == glInterface->fFunctions.fStencilThenCoverFillPath || + NULL == glInterface->fFunctions.fStencilThenCoverStrokePath || + NULL == glInterface->fFunctions.fStencilThenCoverFillPathInstanced || + NULL == glInterface->fFunctions.fStencilThenCoverStrokePathInstanced) { + return new GrGLPathRendering(glInterface); + } + + if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) { + return new GrGLPathRenderingV12(glInterface); + } + + return new GrGLPathRenderingV13(glInterface); +} + +GrGLPathRendering::GrGLPathRendering(const GrGLInterface* glInterface) + : fGLInterface(SkRef(glInterface)) { + memset(&fCaps, 0, sizeof(fCaps)); +} + +GrGLPathRendering::~GrGLPathRendering() { +} + +void GrGLPathRendering::abandonGpuResources() { + fPathNameAllocator.reset(NULL); +} + + +// NV_path_rendering +GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { + if (range > 1) { + GrGLuint name; + GL_CALL_RET(name, GenPaths(range)); + return name; + } + + if (NULL == fPathNameAllocator.get()) { + static const int range = 65536; + GrGLuint firstName; + GL_CALL_RET(firstName, GenPaths(range)); + fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range))); + } + + // When allocating names one at a time, pull from a client-side pool of + // available names in order to save a round trip to the GL server. + GrGLuint name = fPathNameAllocator->allocateName(); + + if (0 == name) { + // Our reserved path names are all in use. Fall back on GenPaths. + GL_CALL_RET(name, GenPaths(1)); + } + + return name; +} + +GrGLvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { + if (range > 1) { + // It is not supported to delete names in ranges that were allocated + // individually using GrGLPathNameAllocator. + SkASSERT(NULL == fPathNameAllocator.get() || + path + range <= fPathNameAllocator->firstName() || + path >= fPathNameAllocator->endName()); + GL_CALL(DeletePaths(path, range)); + return; + } + + if (NULL == fPathNameAllocator.get() || + path < fPathNameAllocator->firstName() || + path >= fPathNameAllocator->endName()) { + // If we aren't inside fPathNameAllocator's range then this name was + // generated by the GenPaths fallback (or else was never allocated). + GL_CALL(DeletePaths(path, 1)); + return; + } + + // Make the path empty to save memory, but don't free the name in the driver. + GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL)); + fPathNameAllocator->free(path); +} + +GrGLvoid GrGLPathRendering::pathCommands(GrGLuint path, GrGLsizei numCommands, + const GrGLubyte *commands, GrGLsizei numCoords, + GrGLenum coordType, const GrGLvoid *coords) { + GL_CALL(PathCommands(path, numCommands, commands, numCoords, coordType, coords)); +} + +GrGLvoid GrGLPathRendering::pathCoords(GrGLuint path, GrGLsizei numCoords, + GrGLenum coordType, const GrGLvoid *coords) { + GL_CALL(PathCoords(path, numCoords, coordType, coords)); +} + +GrGLvoid GrGLPathRendering::pathParameteri(GrGLuint path, GrGLenum pname, GrGLint value) { + GL_CALL(PathParameteri(path, pname, value)); +} + +GrGLvoid GrGLPathRendering::pathParameterf(GrGLuint path, GrGLenum pname, GrGLfloat value) { + GL_CALL(PathParameterf(path, pname, value)); +} + +GrGLboolean GrGLPathRendering::isPath(GrGLuint path) { + GrGLboolean ret; + GL_CALL_RET(ret, IsPath(path)); + return ret; +} + +GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) { + GL_CALL(PathStencilFunc(func, ref, mask)); +} + +GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, GrGLuint mask) { + GL_CALL(StencilFillPath(path, fillMode, mask)); +} + +GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference, GrGLuint mask) { + GL_CALL(StencilStrokePath(path, reference, mask)); +} + +GrGLvoid GrGLPathRendering::stencilFillPathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, + GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues)); +} + +GrGLvoid GrGLPathRendering::stencilStrokePathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLint reference, GrGLuint mask, + GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues)); +} + +GrGLvoid GrGLPathRendering::pathTexGen(GrGLenum texCoordSet, GrGLenum genMode, + GrGLint components, const GrGLfloat *coeffs) { + GL_CALL(PathTexGen(texCoordSet, genMode, components, coeffs)); +} + +GrGLvoid GrGLPathRendering::coverFillPath(GrGLuint path, GrGLenum coverMode) { + GL_CALL(CoverFillPath(path, coverMode)); +} + +GrGLvoid GrGLPathRendering::coverStrokePath(GrGLuint name, GrGLenum coverMode) { + GL_CALL(CoverStrokePath(name, coverMode)); +} + +GrGLvoid GrGLPathRendering::coverFillPathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, + GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)); +} + +GrGLvoid GrGLPathRendering::coverStrokePathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase, + GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transformValues) { + GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)); +} + +GrGLvoid GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, + GrGLuint mask, GrGLenum coverMode) { + GL_CALL(StencilFillPath(path, fillMode, mask)); + GL_CALL(CoverFillPath(path, coverMode)); +} + +GrGLvoid GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference, + GrGLuint mask, GrGLenum coverMode) { + GL_CALL(StencilStrokePath(path, reference, mask)); + GL_CALL(CoverStrokePath(path, coverMode)); +} + +GrGLvoid GrGLPathRendering::stencilThenCoverFillPathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, + fillMode, mask, transformType, transformValues)); + GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)); +} + +GrGLvoid GrGLPathRendering::stencilThenCoverStrokePathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, + reference, mask, transformType, transformValues)); + GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, + coverMode, transformType, transformValues)); +} + +GrGLvoid GrGLPathRendering::programPathFragmentInputGen( + GrGLuint program, GrGLint location, GrGLenum genMode, + GrGLint components, const GrGLfloat *coeffs) { + SkFAIL("ProgramPathFragmentInputGen not supported in this GL context."); +} + + +// NV_path_rendering v1.2 +GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, + GrGLuint mask, GrGLenum coverMode) { + GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode)); +} + +GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference, + GrGLuint mask, GrGLenum coverMode) { + GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode)); +} + +GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode, + mask, coverMode, transformType, transformValues)); +} + +GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues) { + GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, reference, + mask, coverMode, transformType, transformValues)); +} + + +// NV_path_rendering v1.3 +GrGLvoid GrGLPathRenderingV13::programPathFragmentInputGen( + GrGLuint program, GrGLint location, GrGLenum genMode, + GrGLint components, const GrGLfloat *coeffs) { + GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components, coeffs)); +} diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h new file mode 100644 index 0000000000..53b8750356 --- /dev/null +++ b/src/gpu/gl/GrGLPathRendering.h @@ -0,0 +1,108 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLPathRendering_DEFINED +#define GrGLPathRendering_DEFINED + +#include "SkRefCnt.h" +#include "gl/GrGLFunctions.h" + +class GrGLNameAllocator; +struct GrGLInterface; + +/** + * This class wraps the NV_path_rendering extension and manages its various + * API versions. If a method is not present in the GrGLInterface (because the + * driver version is old), it tries to provide a backup implementation. But if + * a backup implementation is not practical, it marks the method as not + * supported. + */ +class GrGLPathRendering { +public: + /** + * Create a new GrGLPathRendering object from a given GL interface. Unless + * otherwise specified in the caps, every method will work properly, even + * if it did not exist in the GL interface. + */ + static GrGLPathRendering* Create(const GrGLInterface*); + virtual ~GrGLPathRendering(); + + /** + * Mark certain functionality as not supported if the driver version is too + * old and a backup implementation is not practical. + */ + struct Caps { + bool fragmentInputGenSupport : 1; + }; + const Caps& caps() const { return fCaps; } + + /** + * Called when the GPU resources have been lost and need to be abandoned + * (for example after a context loss). + */ + void abandonGpuResources(); + + // NV_path_rendering + GrGLuint genPaths(GrGLsizei range); + GrGLvoid deletePaths(GrGLuint path, GrGLsizei range); + GrGLvoid pathCommands(GrGLuint path, GrGLsizei numCommands, const GrGLubyte *commands, + GrGLsizei numCoords, GrGLenum coordType, const GrGLvoid *coords); + GrGLvoid pathCoords(GrGLuint path, GrGLsizei numCoords, + GrGLenum coordType, const GrGLvoid *coords); + GrGLvoid pathParameteri(GrGLuint path, GrGLenum pname, GrGLint value); + GrGLvoid pathParameterf(GrGLuint path, GrGLenum pname, GrGLfloat value); + GrGLboolean isPath(GrGLuint path); + GrGLvoid pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask); + GrGLvoid stencilFillPath(GrGLuint path, GrGLenum fillMode, GrGLuint mask); + GrGLvoid stencilStrokePath(GrGLuint path, GrGLint reference, GrGLuint mask); + GrGLvoid stencilFillPathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, + const GrGLvoid *paths, GrGLuint pathBase, GrGLenum fillMode, + GrGLuint mask, GrGLenum transformType, + const GrGLfloat *transformValues); + GrGLvoid stencilStrokePathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, + const GrGLvoid *paths, GrGLuint pathBase, + GrGLint reference, GrGLuint mask, GrGLenum transformType, + const GrGLfloat *transformValues); + GrGLvoid pathTexGen(GrGLenum texCoordSet, GrGLenum genMode, + GrGLint components, const GrGLfloat *coeffs); + GrGLvoid coverFillPath(GrGLuint path, GrGLenum coverMode); + GrGLvoid coverStrokePath(GrGLuint name, GrGLenum coverMode); + GrGLvoid coverFillPathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, + const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues); + GrGLvoid coverStrokePathInstanced(GrGLsizei numPaths, GrGLenum pathNameType, + const GrGLvoid *paths, GrGLuint pathBase, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat* transformValues); + + // NV_path_rendering v1.2 + virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, + GrGLuint mask, GrGLenum coverMode); + virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference, + GrGLuint mask, GrGLenum coverMode); + virtual GrGLvoid stencilThenCoverFillPathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues); + virtual GrGLvoid stencilThenCoverStrokePathInstanced( + GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, + GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, + GrGLenum transformType, const GrGLfloat *transformValues); + + // NV_path_rendering v1.3 + virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint location, + GrGLenum genMode, GrGLint components, + const GrGLfloat *coeffs); + +protected: + GrGLPathRendering(const GrGLInterface*); + + SkAutoTUnref<const GrGLInterface> fGLInterface; + SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator; + Caps fCaps; +}; + +#endif diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index adcddcc108..52caf9d3ea 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -7,10 +7,10 @@ #include "GrGpuGL.h" -#include "GrGLNameAllocator.h" #include "GrGLStencilBuffer.h" #include "GrGLPath.h" #include "GrGLPathRange.h" +#include "GrGLPathRendering.h" #include "GrGLShaderBuilder.h" #include "GrTemplates.h" #include "GrTypes.h" @@ -164,6 +164,10 @@ GrGpuGL::GrGpuGL(const GrGLContext& ctx, GrContext* context) fLastSuccessfulStencilFmtIdx = 0; fHWProgramID = 0; + + if (this->glCaps().pathRenderingSupport()) { + fPathRendering.reset(GrGLPathRendering::Create(glInterface())); + } } GrGpuGL::~GrGpuGL() { @@ -329,7 +333,7 @@ void GrGpuGL::onResetContext(uint32_t resetBits) { GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW)); for (int i = 0; i < this->glCaps().maxFixedFunctionTextureCoords(); ++i) { - GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); + fPathRendering->pathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL); fHWPathTexGenSettings[i].fMode = GR_GL_NONE; fHWPathTexGenSettings[i].fNumComponents = 0; } @@ -1881,7 +1885,7 @@ void GrGpuGL::onGpuStencilPath(const GrPath* path, SkPath::FillType fill) { GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); - GL_CALL(StencilFillPath(id, fillMode, writeMask)); + fPathRendering->stencilFillPath(id, fillMode, writeMask); } void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) { @@ -1904,18 +1908,18 @@ void GrGpuGL::onGpuDrawPath(const GrPath* path, SkPath::FillType fill) { if (nonInvertedFill == fill) { if (stroke.needToApply()) { if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { - GL_CALL(StencilFillPath(id, fillMode, writeMask)); + fPathRendering->stencilFillPath(id, fillMode, writeMask); } - GL_CALL(StencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX)); + fPathRendering->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDING_BOX); } else { - GL_CALL(StencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX)); + fPathRendering->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDING_BOX); } } else { if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { - GL_CALL(StencilFillPath(id, fillMode, writeMask)); + fPathRendering->stencilFillPath(id, fillMode, writeMask); } if (stroke.needToApply()) { - GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); + fPathRendering->stencilStrokePath(id, 0xffff, writeMask); } GrDrawState* drawState = this->drawState(); @@ -1966,33 +1970,33 @@ void GrGpuGL::onGpuDrawPaths(const GrPathRange* pathRange, if (nonInvertedFill == fill) { if (stroke.needToApply()) { if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { - GL_CALL(StencilFillPathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, - writeMask, gXformType2GLType[transformsType], - transforms)); + fPathRendering->stencilFillPathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, + writeMask, gXformType2GLType[transformsType], + transforms); } - GL_CALL(StencilThenCoverStrokePathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask, - GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, - gXformType2GLType[transformsType], transforms)); + fPathRendering->stencilThenCoverStrokePathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask, + GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, + gXformType2GLType[transformsType], transforms); } else { - GL_CALL(StencilThenCoverFillPathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask, - GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, - gXformType2GLType[transformsType], transforms)); + fPathRendering->stencilThenCoverFillPathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask, + GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, + gXformType2GLType[transformsType], transforms); } } else { if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { - GL_CALL(StencilFillPathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, - writeMask, gXformType2GLType[transformsType], - transforms)); + fPathRendering->stencilFillPathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, + writeMask, gXformType2GLType[transformsType], + transforms); } if (stroke.needToApply()) { - GL_CALL(StencilStrokePathInstanced( - count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, - writeMask, gXformType2GLType[transformsType], - transforms)); + fPathRendering->stencilStrokePathInstanced( + count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, + writeMask, gXformType2GLType[transformsType], + transforms); } GrDrawState* drawState = this->drawState(); @@ -2210,9 +2214,9 @@ void GrGpuGL::flushPathStencilSettings(SkPath::FillType fill) { // that draws the path to the SB (glStencilFillPath) GrGLenum func = gr_to_gl_stencil_func(pathStencilSettings.func(GrStencilSettings::kFront_Face)); - GL_CALL(PathStencilFunc(func, - pathStencilSettings.funcRef(GrStencilSettings::kFront_Face), - pathStencilSettings.funcMask(GrStencilSettings::kFront_Face))); + fPathRendering->pathStencilFunc( + func, pathStencilSettings.funcRef(GrStencilSettings::kFront_Face), + pathStencilSettings.funcMask(GrStencilSettings::kFront_Face)); fHWPathStencilSettings = pathStencilSettings; } @@ -2403,10 +2407,10 @@ void GrGpuGL::enablePathTexGen(int unitIdx, this->setTextureUnit(unitIdx); fHWPathTexGenSettings[unitIdx].fNumComponents = components; - GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, - GR_GL_OBJECT_LINEAR, - components, - coefficients)); + fPathRendering->pathTexGen(GR_GL_TEXTURE0 + unitIdx, + GR_GL_OBJECT_LINEAR, + components, + coefficients); memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients, 3 * components * sizeof(GrGLfloat)); @@ -2455,7 +2459,7 @@ void GrGpuGL::flushPathTexGenSettings(int numUsedTexCoordSets) { SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); this->setTextureUnit(i); - GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); + fPathRendering->pathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL); fHWPathTexGenSettings[i].fNumComponents = 0; } @@ -2511,38 +2515,6 @@ void GrGpuGL::flushMiscFixedFunctionState() { } } -GrGLuint GrGpuGL::createGLPathObject() { - if (NULL == fPathNameAllocator.get()) { - static const int range = 65536; - GrGLuint firstName; - GL_CALL_RET(firstName, GenPaths(range)); - fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range))); - } - - GrGLuint name = fPathNameAllocator->allocateName(); - if (0 == name) { - // Our reserved path names are all in use. Fall back on GenPaths. - GL_CALL_RET(name, GenPaths(1)); - } - - return name; -} - -void GrGpuGL::deleteGLPathObject(GrGLuint name) { - if (NULL == fPathNameAllocator.get() || - name < fPathNameAllocator->firstName() || - name >= fPathNameAllocator->endName()) { - // If we aren't inside fPathNameAllocator's range then this name was - // generated by the GenPaths fallback (or else the name is unallocated). - GL_CALL(DeletePaths(name, 1)); - return; - } - - // Make the path empty to save memory, but don't free the name in the driver. - GL_CALL(PathCommands(name, 0, NULL, 0, GR_GL_FLOAT, NULL)); - fPathNameAllocator->free(name); -} - bool GrGpuGL::configToGLFormats(GrPixelConfig config, bool getSizedInternalFormat, GrGLenum* internalFormat, diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index e67197219d..b39aedb824 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -24,7 +24,7 @@ #define PROGRAM_CACHE_STATS #endif -class GrGLNameAllocator; +class GrGLPathRendering; class GrGpuGL : public GrGpu { public: @@ -40,6 +40,11 @@ public: GrGLSLGeneration glslGeneration() const { return fGLContext.glslGeneration(); } const GrGLCaps& glCaps() const { return *fGLContext.caps(); } + GrGLPathRendering* pathRendering() const { + SkASSERT(glCaps().pathRenderingSupport()); + return fPathRendering.get(); + } + virtual void discard(GrRenderTarget*) SK_OVERRIDE; // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL @@ -104,11 +109,6 @@ public: fHWGeometryState.notifyIndexBufferDelete(id); } - // These functions should be used to generate and delete GL path names. They have their own - // allocator that runs on the client side, so they are much faster than going through GenPaths. - GrGLuint createGLPathObject(); - void deleteGLPathObject(GrGLuint); - protected: virtual bool onCopySurface(GrSurface* dst, GrSurface* src, @@ -470,7 +470,7 @@ private: // from our loop that tries stencil formats and calls check fb status. int fLastSuccessfulStencilFmtIdx; - SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator; + SkAutoTDelete<GrGLPathRendering> fPathRendering; typedef GrGpu INHERITED; }; diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 2afb95fe97..139d5cfa44 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -10,7 +10,7 @@ #include "GrEffect.h" #include "GrGLEffect.h" #include "SkRTConf.h" -#include "GrGLNameAllocator.h" +#include "GrGLPathRendering.h" #include "SkTSearch.h" #ifdef PROGRAM_CACHE_STATS @@ -203,7 +203,7 @@ void GrGpuGL::abandonResources(){ INHERITED::abandonResources(); fProgramCache->abandon(); fHWProgramID = 0; - fPathNameAllocator.reset(NULL); + fPathRendering->abandonGpuResources(); } //////////////////////////////////////////////////////////////////////////////// |