aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu')
-rwxr-xr-xsrc/gpu/GrContextFactory.cpp23
-rw-r--r--src/gpu/gl/GrGLAssembleInterface.cpp5
-rw-r--r--src/gpu/gl/GrGLCaps.cpp45
-rw-r--r--src/gpu/gl/GrGLCaps.h1
-rw-r--r--src/gpu/gl/GrGLGpu.h3
-rw-r--r--src/gpu/gl/GrGLInterface.cpp32
-rw-r--r--src/gpu/gl/GrGLPathRendering.cpp78
-rw-r--r--src/gpu/gl/GrGLPathRendering.h33
8 files changed, 69 insertions, 151 deletions
diff --git a/src/gpu/GrContextFactory.cpp b/src/gpu/GrContextFactory.cpp
index 7df19177eb..edef2f7db1 100755
--- a/src/gpu/GrContextFactory.cpp
+++ b/src/gpu/GrContextFactory.cpp
@@ -17,7 +17,8 @@
#endif
#include "gl/SkGLContext.h"
#include "gl/SkNullGLContext.h"
-
+#include "gl/GrGLGpu.h"
+#include "GrCaps.h"
GrContext* GrContextFactory::get(GLContextType type, GrGLStandard forcedGpuAPI) {
for (int i = 0; i < fContexts.count(); ++i) {
@@ -60,13 +61,9 @@ GrContext* GrContextFactory::get(GLContextType type, GrGLStandard forcedGpuAPI)
SkASSERT(glCtx->isValid());
- // Ensure NVPR is available for the NVPR type and block it from other types.
+ // Block NVPR from non-NVPR types.
SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx->gl()));
- if (kNVPR_GLContextType == type) {
- if (!glInterface->hasExtension("GL_NV_path_rendering")) {
- return NULL;
- }
- } else {
+ if (kNVPR_GLContextType != type) {
glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
if (!glInterface) {
return NULL;
@@ -79,6 +76,18 @@ GrContext* GrContextFactory::get(GLContextType type, GrGLStandard forcedGpuAPI)
if (!grCtx.get()) {
return NULL;
}
+ // Warn if path rendering support is not available for the NVPR type.
+ if (kNVPR_GLContextType == type) {
+ if (!grCtx->caps()->shaderCaps()->pathRenderingSupport()) {
+ GrGLGpu* gpu = static_cast<GrGLGpu*>(grCtx->getGpu());
+ const GrGLubyte* verUByte;
+ GR_GL_CALL_RET(gpu->glInterface(), verUByte, GetString(GR_GL_VERSION));
+ const char* ver = reinterpret_cast<const char*>(verUByte);
+ SkDebugf("\nWARNING: nvprmsaa config requested, but driver path rendering support not"
+ " available. Maybe update the driver? Your driver version string: \"%s\"\n", ver);
+ }
+ }
+
GPUContext& ctx = fContexts.push_back();
ctx.fGLContext = glCtx.get();
ctx.fGLContext->ref();
diff --git a/src/gpu/gl/GrGLAssembleInterface.cpp b/src/gpu/gl/GrGLAssembleInterface.cpp
index 1fe53ebc3e..3f66c0388a 100644
--- a/src/gpu/gl/GrGLAssembleInterface.cpp
+++ b/src/gpu/gl/GrGLAssembleInterface.cpp
@@ -273,7 +273,6 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC_SUFFIX(MatrixLoadf, EXT);
GET_PROC_SUFFIX(MatrixLoadIdentity, EXT);
GET_PROC_SUFFIX(PathCommands, NV);
- GET_PROC_SUFFIX(PathCoords, NV);
GET_PROC_SUFFIX(PathParameteri, NV);
GET_PROC_SUFFIX(PathParameterf, NV);
GET_PROC_SUFFIX(GenPaths, NV);
@@ -284,17 +283,14 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC_SUFFIX(StencilStrokePath, NV);
GET_PROC_SUFFIX(StencilFillPathInstanced, NV);
GET_PROC_SUFFIX(StencilStrokePathInstanced, NV);
- GET_PROC_SUFFIX(PathTexGen, NV);
GET_PROC_SUFFIX(CoverFillPath, NV);
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);
}
@@ -682,7 +678,6 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC_SUFFIX(MatrixLoadf, EXT);
GET_PROC_SUFFIX(MatrixLoadIdentity, EXT);
GET_PROC_SUFFIX(PathCommands, NV);
- GET_PROC_SUFFIX(PathCoords, NV);
GET_PROC_SUFFIX(PathParameteri, NV);
GET_PROC_SUFFIX(PathParameterf, NV);
GET_PROC_SUFFIX(GenPaths, NV);
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index feb45eab88..539212c3a5 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -279,21 +279,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
* GrShaderCaps fields
**************************************************************************/
- glslCaps->fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering");
-
- if (glslCaps->fPathRenderingSupport) {
- if (kGL_GrGLStandard == standard) {
- // We only support v1.3+ of GL_NV_path_rendering which allows us to
- // set individual fragment inputs with ProgramPathFragmentInputGen. The API
- // additions are detected by checking the existence of the function.
- glslCaps->fPathRenderingSupport = ((ctxInfo.version() >= GR_GL_VER(4, 3) ||
- ctxInfo.hasExtension("GL_ARB_program_interface_query")) &&
- gli->fFunctions.fProgramPathFragmentInputGen);
- }
- else {
- glslCaps->fPathRenderingSupport = ctxInfo.version() >= GR_GL_VER(3, 1);
- }
- }
+ glslCaps->fPathRenderingSupport = this->hasPathRenderingSupport(ctxInfo, gli);
// For now these two are equivalent but we could have dst read in shader via some other method
glslCaps->fDstReadInShaderSupport = glslCaps->fFBFetchSupport;
@@ -477,6 +463,35 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
glslCaps->applyOptionsOverrides(contextOptions);
}
+bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
+ if (!ctxInfo.hasExtension("GL_NV_path_rendering")) {
+ return false;
+ }
+ if (kGL_GrGLStandard == ctxInfo.standard()) {
+ if (ctxInfo.version() < GR_GL_VER(4, 3) &&
+ !ctxInfo.hasExtension("GL_ARB_program_interface_query")) {
+ return false;
+ }
+ } else {
+ if (ctxInfo.version() < GR_GL_VER(3, 1)) {
+ return false;
+ }
+ }
+ // We only support v1.3+ of GL_NV_path_rendering which allows us to
+ // set individual fragment inputs with ProgramPathFragmentInputGen. The API
+ // additions are detected by checking the existence of the function.
+ // We also use *Then* functions that not all drivers might have. Check
+ // them for consistency.
+ if (NULL == gli->fFunctions.fStencilThenCoverFillPath ||
+ NULL == gli->fFunctions.fStencilThenCoverStrokePath ||
+ NULL == gli->fFunctions.fStencilThenCoverFillPathInstanced ||
+ NULL == gli->fFunctions.fStencilThenCoverStrokePathInstanced ||
+ NULL == gli->fFunctions.fProgramPathFragmentInputGen) {
+ return false;
+ }
+ return true;
+}
+
void GrGLCaps::initConfigRenderableTable(const GrGLContextInfo& ctxInfo) {
// OpenGL < 3.0
// no support for render targets unless the GL_ARB_framebuffer_object
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index 1e07a76ed5..ac90aa1db6 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -281,6 +281,7 @@ public:
private:
void init(const GrContextOptions&, const GrGLContextInfo&, const GrGLInterface*);
+ bool hasPathRenderingSupport(const GrGLContextInfo&, const GrGLInterface*);
/**
* Maintains a bit per GrPixelConfig. It is used to avoid redundantly
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 4872db7309..e5cd7a9a9d 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -54,8 +54,7 @@ public:
void discard(GrRenderTarget*) override;
- // Used by GrGLProgram and GrGLPathTexGenProgramEffects to configure OpenGL
- // state.
+ // Used by GrGLProgram to configure OpenGL state.
void bindTexture(int unitIdx, const GrTextureParams& params, GrGLTexture* texture);
// GrGpu overrides
diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp
index 3d44f6d602..56f1e59275 100644
--- a/src/gpu/gl/GrGLInterface.cpp
+++ b/src/gpu/gl/GrGLInterface.cpp
@@ -40,7 +40,6 @@ const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) {
newInterface->fExtensions.remove("GL_NV_path_rendering");
newInterface->fFunctions.fPathCommands = NULL;
- newInterface->fFunctions.fPathCoords = NULL;
newInterface->fFunctions.fPathParameteri = NULL;
newInterface->fFunctions.fPathParameterf = NULL;
newInterface->fFunctions.fGenPaths = NULL;
@@ -51,7 +50,6 @@ const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) {
newInterface->fFunctions.fStencilStrokePath = NULL;
newInterface->fFunctions.fStencilFillPathInstanced = NULL;
newInterface->fFunctions.fStencilStrokePathInstanced = NULL;
- newInterface->fFunctions.fPathTexGen = NULL;
newInterface->fFunctions.fCoverFillPath = NULL;
newInterface->fFunctions.fCoverStrokePath = NULL;
newInterface->fFunctions.fCoverFillPathInstanced = NULL;
@@ -489,7 +487,6 @@ bool GrGLInterface::validate() const {
if (NULL == fFunctions.fMatrixLoadf ||
NULL == fFunctions.fMatrixLoadIdentity ||
NULL == fFunctions.fPathCommands ||
- NULL == fFunctions.fPathCoords ||
NULL == fFunctions.fPathParameteri ||
NULL == fFunctions.fPathParameterf ||
NULL == fFunctions.fGenPaths ||
@@ -503,24 +500,21 @@ bool GrGLInterface::validate() const {
NULL == fFunctions.fCoverFillPath ||
NULL == fFunctions.fCoverStrokePath ||
NULL == fFunctions.fCoverFillPathInstanced ||
- NULL == fFunctions.fCoverStrokePathInstanced) {
+ NULL == fFunctions.fCoverStrokePathInstanced
+#if 0
+ // List of functions that Skia uses, but which have been added since the initial release
+ // of NV_path_rendering driver. We do not want to fail interface validation due to
+ // missing features, we will just not use the extension.
+ // Update this list -> update GrGLCaps::hasPathRenderingSupport too.
+ || NULL == fFunctions.fStencilThenCoverFillPath ||
+ NULL == fFunctions.fStencilThenCoverStrokePath ||
+ NULL == fFunctions.fStencilThenCoverFillPathInstanced ||
+ NULL == fFunctions.fStencilThenCoverStrokePathInstanced ||
+ NULL == fFunctions.fProgramPathFragmentInputGen
+#endif
+ ) {
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
- }
- }
}
if (fExtensions.has("GL_EXT_raster_multisample")) {
diff --git a/src/gpu/gl/GrGLPathRendering.cpp b/src/gpu/gl/GrGLPathRendering.cpp
index eb9f5a86f7..ffdbbdab26 100644
--- a/src/gpu/gl/GrGLPathRendering.cpp
+++ b/src/gpu/gl/GrGLPathRendering.cpp
@@ -61,16 +61,6 @@ static GrGLenum gr_stencil_op_to_gl_path_rendering_fill_mode(GrStencilOp op) {
GrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu)
: GrPathRendering(gpu) {
- const GrGLInterface* glInterface = gpu->glInterface();
- fCaps.stencilThenCoverSupport =
- NULL != glInterface->fFunctions.fStencilThenCoverFillPath &&
- NULL != glInterface->fFunctions.fStencilThenCoverStrokePath &&
- NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced &&
- NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced;
- fCaps.fragmentInputGenSupport =
- NULL != glInterface->fFunctions.fProgramPathFragmentInputGen;
-
- SkASSERT(fCaps.fragmentInputGenSupport);
}
GrGLPathRendering::~GrGLPathRendering() {
@@ -85,7 +75,6 @@ void GrGLPathRendering::resetContext() {
// we don't use the model view matrix.
GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW));
- SkASSERT(fCaps.fragmentInputGenSupport);
fHWPathStencilSettings.invalidate();
}
@@ -145,9 +134,11 @@ void GrGLPathRendering::onDrawPath(const DrawPathArgs& args, const GrPath* path)
if (glPath->shouldFill()) {
GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask));
}
- this->stencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask, GR_GL_BOUNDING_BOX);
+ GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask,
+ GR_GL_BOUNDING_BOX));
} else {
- this->stencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask, GR_GL_BOUNDING_BOX);
+ GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask,
+ GR_GL_BOUNDING_BOX));
}
}
@@ -177,22 +168,21 @@ void GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange*
fillMode, writeMask, gXformType2GLType[transformType],
transformValues));
}
- this->stencilThenCoverStrokePathInstanced(
+ GL_CALL(StencilThenCoverStrokePathInstanced(
count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
- gXformType2GLType[transformType], transformValues);
+ gXformType2GLType[transformType], transformValues));
} else {
- this->stencilThenCoverFillPathInstanced(
+ GL_CALL(StencilThenCoverFillPathInstanced(
count, gIndexType2GLType[indexType], indices, glPathRange->basePathID(),
fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
- gXformType2GLType[transformType], transformValues);
+ gXformType2GLType[transformType], transformValues));
}
}
void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location,
GrGLenum genMode, GrGLint components,
const SkMatrix& matrix) {
- SkASSERT(caps().fragmentInputGenSupport);
GrGLfloat coefficients[3 * 3];
SkASSERT(components >= 1 && components <= 3);
@@ -300,58 +290,6 @@ void GrGLPathRendering::flushPathStencilSettings(const GrStencilSettings& stenci
}
}
-inline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
- GrGLuint mask, GrGLenum coverMode) {
- if (caps().stencilThenCoverSupport) {
- GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode));
- return;
- }
- GL_CALL(StencilFillPath(path, fillMode, mask));
- GL_CALL(CoverFillPath(path, coverMode));
-}
-
-inline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
- GrGLuint mask, GrGLenum coverMode) {
- if (caps().stencilThenCoverSupport) {
- GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode));
- return;
- }
- GL_CALL(StencilStrokePath(path, reference, mask));
- GL_CALL(CoverStrokePath(path, coverMode));
-}
-
-inline void GrGLPathRendering::stencilThenCoverFillPathInstanced(
- GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
- GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
- GrGLenum transformType, const GrGLfloat *transformValues) {
- if (caps().stencilThenCoverSupport) {
- GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
- mask, coverMode, transformType, transformValues));
- return;
- }
- GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
- fillMode, mask, transformType, transformValues));
- GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
- coverMode, transformType, transformValues));
-}
-
-inline void GrGLPathRendering::stencilThenCoverStrokePathInstanced(
- GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
- GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
- GrGLenum transformType, const GrGLfloat *transformValues) {
- if (caps().stencilThenCoverSupport) {
- GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
- reference, mask, coverMode, transformType,
- transformValues));
- return;
- }
-
- GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
- reference, mask, transformType, transformValues));
- GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
- coverMode, transformType, transformValues));
-}
-
inline GrGLGpu* GrGLPathRendering::gpu() {
return static_cast<GrGLGpu*>(fGpu);
}
diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h
index 20fd4967b7..86cf1b1698 100644
--- a/src/gpu/gl/GrGLPathRendering.h
+++ b/src/gpu/gl/GrGLPathRendering.h
@@ -65,35 +65,8 @@ protected:
void onDrawPaths(const DrawPathArgs&, const GrPathRange*, const void* indices, PathIndexType,
const float transformValues[], PathTransformType, int count) override;
private:
- /**
- * Mark certain functionality as not supported if the driver version is too
- * old and a backup implementation is not practical.
- */
- struct Caps {
- bool stencilThenCoverSupport : 1;
- bool fragmentInputGenSupport : 1;
- };
- const Caps& caps() const { return fCaps; }
-
void flushPathStencilSettings(const GrStencilSettings&);
- // NV_path_rendering v1.2
- void stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
- GrGLuint mask, GrGLenum coverMode);
-
- void stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
- GrGLuint mask, GrGLenum coverMode);
-
- void stencilThenCoverFillPathInstanced(
- GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
- GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
- GrGLenum transformType, const GrGLfloat *transformValues);
-
- void stencilThenCoverStrokePathInstanced(
- GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
- GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
- GrGLenum transformType, const GrGLfloat *transformValues);
-
struct MatrixState {
SkMatrix fViewMatrix;
SkISize fRenderTargetSize;
@@ -128,14 +101,8 @@ private:
GrGLGpu* gpu();
SkAutoTDelete<GrGLNameAllocator> fPathNameAllocator;
- Caps fCaps;
MatrixState fHWProjectionMatrixState;
GrStencilSettings fHWPathStencilSettings;
- struct PathTexGenData {
- GrGLenum fMode;
- GrGLint fNumComponents;
- GrGLfloat fCoefficients[3 * 3];
- };
};
#endif