Turn NVPR on by default (but off in tools).
BUG=skia:2042 R=robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/144003006 git-svn-id: http://skia.googlecode.com/svn/trunk@13164 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
1c2f8c2973
commit
83d81c96de
File diff suppressed because it is too large
Load Diff
@ -86,7 +86,6 @@
|
||||
'skia_sanitizer%': '',
|
||||
'skia_scalar%': 'float',
|
||||
'skia_mesa%': 0,
|
||||
'skia_nv_path_rendering%': 0,
|
||||
'skia_stroke_path_rendering%': 0,
|
||||
'skia_android_path_rendering%': 0,
|
||||
'skia_resource_cache_mb_limit%': 0,
|
||||
@ -145,7 +144,6 @@
|
||||
'skia_sanitizer%': '<(skia_sanitizer)',
|
||||
'skia_scalar%': '<(skia_scalar)',
|
||||
'skia_mesa%': '<(skia_mesa)',
|
||||
'skia_nv_path_rendering%': '<(skia_nv_path_rendering)',
|
||||
'skia_stroke_path_rendering%': '<(skia_stroke_path_rendering)',
|
||||
'skia_android_path_rendering%': '<(skia_android_path_rendering)',
|
||||
'skia_resource_cache_mb_limit%': '<(skia_resource_cache_mb_limit)',
|
||||
|
@ -107,11 +107,6 @@
|
||||
'gpu.gypi', # Makes the gypi appear in IDEs (but does not modify the build).
|
||||
],
|
||||
'conditions': [
|
||||
[ 'skia_nv_path_rendering', {
|
||||
'defines': [
|
||||
'GR_GL_USE_NV_PATH_RENDERING=1',
|
||||
],
|
||||
}],
|
||||
[ 'skia_stroke_path_rendering', {
|
||||
'sources': [
|
||||
'../experimental/StrokePathRenderer/GrStrokePathRenderer.h',
|
||||
|
@ -26,12 +26,15 @@
|
||||
* GrContexts backed by different types of GL contexts. It manages creating the
|
||||
* GL context and a GrContext that uses it. The GL/Gr contexts persist until the
|
||||
* factory is destroyed (though the caller can always grab a ref on the returned
|
||||
* GrContext to make it outlive the factory).
|
||||
* Gr and GL contexts to make them outlive the factory).
|
||||
*/
|
||||
class GrContextFactory : public SkNoncopyable {
|
||||
public:
|
||||
/**
|
||||
* Types of GL contexts supported.
|
||||
* Types of GL contexts supported. For historical and testing reasons the native GrContext will
|
||||
* not use "GL_NV_path_rendering" even when the driver supports it. There is a separate context
|
||||
* type that does not remove NVPR support and which will fail when the driver does not support
|
||||
* the extension.
|
||||
*/
|
||||
enum GLContextType {
|
||||
kNative_GLContextType,
|
||||
@ -41,6 +44,9 @@ public:
|
||||
#if SK_MESA
|
||||
kMESA_GLContextType,
|
||||
#endif
|
||||
/** Similar to kNative but does not filter NVPR. It will fail if the GL driver does not
|
||||
support NVPR */
|
||||
kNVPR_GLContextType,
|
||||
kNull_GLContextType,
|
||||
kDebug_GLContextType,
|
||||
|
||||
@ -73,6 +79,8 @@ public:
|
||||
case kMESA_GLContextType:
|
||||
return "mesa";
|
||||
#endif
|
||||
case kNVPR_GLContextType:
|
||||
return "nvpr";
|
||||
case kDebug_GLContextType:
|
||||
return "debug";
|
||||
default:
|
||||
@ -87,6 +95,7 @@ public:
|
||||
|
||||
void destroyContexts() {
|
||||
for (int i = 0; i < fContexts.count(); ++i) {
|
||||
fContexts[i].fGLContext->makeCurrent();
|
||||
fContexts[i].fGrContext->unref();
|
||||
fContexts[i].fGLContext->unref();
|
||||
}
|
||||
@ -107,6 +116,7 @@ public:
|
||||
SkAutoTUnref<SkGLContextHelper> glCtx;
|
||||
SkAutoTUnref<GrContext> grCtx;
|
||||
switch (type) {
|
||||
case kNVPR_GLContextType: // fallthru
|
||||
case kNative_GLContextType:
|
||||
glCtx.reset(SkNEW(SkNativeGLContext));
|
||||
break;
|
||||
@ -134,7 +144,22 @@ public:
|
||||
if (!glCtx.get()->init(kBogusSize, kBogusSize)) {
|
||||
return NULL;
|
||||
}
|
||||
GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glCtx.get()->gl());
|
||||
|
||||
// Ensure NVPR is available for the NVPR type and block it from other types.
|
||||
SkAutoTUnref<const GrGLInterface> glInterface(SkRef(glCtx.get()->gl()));
|
||||
if (kNVPR_GLContextType == type) {
|
||||
if (!glInterface->hasExtension("GL_NV_path_rendering")) {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
glInterface.reset(GrGLInterfaceRemoveNVPR(glInterface));
|
||||
if (!glInterface) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
glCtx->makeCurrent();
|
||||
GrBackendContext p3dctx = reinterpret_cast<GrBackendContext>(glInterface.get());
|
||||
grCtx.reset(GrContext::Create(kOpenGL_GrBackend, p3dctx));
|
||||
if (!grCtx.get()) {
|
||||
return NULL;
|
||||
|
@ -93,10 +93,6 @@
|
||||
* stencil formats as attachments. If the FBO is complete we will assume
|
||||
* subsequent attachments with the same formats are complete as well.
|
||||
*
|
||||
* GR_GL_USE_NV_PATH_RENDERING: Enable experimental support for
|
||||
* GL_NV_path_rendering. There are known issues with clipping, non-AA paths, and
|
||||
* perspective.
|
||||
*
|
||||
* GR_GL_MUST_USE_VBO: Indicates that all vertices and indices must be rendered
|
||||
* from VBOs. Chromium's command buffer doesn't allow glVertexAttribArray with
|
||||
* ARARY_BUFFER 0 bound or glDrawElements with ELEMENT_ARRAY_BUFFER 0 bound.
|
||||
@ -158,10 +154,6 @@
|
||||
#define GR_GL_CHECK_FBO_STATUS_ONCE_PER_FORMAT 0
|
||||
#endif
|
||||
|
||||
#if !defined(GR_GL_USE_NV_PATH_RENDERING)
|
||||
#define GR_GL_USE_NV_PATH_RENDERING 0
|
||||
#endif
|
||||
|
||||
#if !defined(GR_GL_MUST_USE_VBO)
|
||||
#define GR_GL_MUST_USE_VBO 0
|
||||
#endif
|
||||
|
@ -19,12 +19,17 @@ struct GrGLInterface;
|
||||
* queried. It supports both glGetString- and glGetStringi-style extension string APIs and will
|
||||
* use the latter if it is available.
|
||||
*/
|
||||
class GrGLExtensions : public SkNoncopyable {
|
||||
class GrGLExtensions {
|
||||
public:
|
||||
GrGLExtensions() : fInitialized(false), fStrings(SkNEW(SkTArray<SkString>)) {}
|
||||
|
||||
GrGLExtensions(const GrGLExtensions&);
|
||||
|
||||
GrGLExtensions& operator=(const GrGLExtensions&);
|
||||
|
||||
void swap(GrGLExtensions* that) {
|
||||
fStrings.swap(&that->fStrings);
|
||||
SkTSwap(fInitialized, that->fInitialized);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +47,12 @@ public:
|
||||
/**
|
||||
* Queries whether an extension is present. This will fail if init() has not been called.
|
||||
*/
|
||||
bool has(const char*) const;
|
||||
bool has(const char[]) const;
|
||||
|
||||
/**
|
||||
* Removes an extension if present. Returns true if the extension was present before the call.
|
||||
*/
|
||||
bool remove(const char[]);
|
||||
|
||||
void reset() { fStrings->reset(); }
|
||||
|
||||
|
@ -72,7 +72,11 @@ typedef void (*GrGLInterfaceCallbackProc)(const GrGLInterface*);
|
||||
typedef intptr_t GrGLInterfaceCallbackData;
|
||||
#endif
|
||||
|
||||
/*
|
||||
/** Function that returns a new interface identical to "interface" but without support for
|
||||
GL_NV_path_rendering. */
|
||||
const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface);
|
||||
|
||||
/**
|
||||
* GrContext uses the following interface to make all calls into OpenGL. When a
|
||||
* GrContext is created it is given a GrGLInterface. The interface's function
|
||||
* pointers must be valid for the OpenGL context associated with the GrContext.
|
||||
@ -112,6 +116,8 @@ public:
|
||||
|
||||
GrGLInterface();
|
||||
|
||||
static GrGLInterface* NewClone(const GrGLInterface*);
|
||||
|
||||
// Validates that the GrGLInterface supports its advertised standard. This means the necessary
|
||||
// function pointers have been initialized for both the GL version and any advertised
|
||||
// extensions.
|
||||
@ -358,7 +364,6 @@ public:
|
||||
GLPtr<GrGLPointAlongPathProc> fPointAlongPath;
|
||||
} fFunctions;
|
||||
|
||||
|
||||
// Temporary workaround aliases to keep Chromium GrGLInterface factories compiling until they
|
||||
// assign the members of fFunctions.
|
||||
GLPtrAlias<GrGLActiveTextureProc> fActiveTexture;
|
||||
|
@ -210,6 +210,7 @@ public:
|
||||
fMSAASampleCount = msaaSampleCount;
|
||||
|
||||
SkASSERT(NULL == fCurIntf);
|
||||
SkAutoTUnref<const GrGLInterface> glInterface;
|
||||
switch (win->getDeviceType()) {
|
||||
case kRaster_DeviceType:
|
||||
// fallthrough
|
||||
@ -217,21 +218,25 @@ public:
|
||||
// fallthrough
|
||||
case kGPU_DeviceType:
|
||||
// all these guys use the native interface
|
||||
fCurIntf = GrGLCreateNativeInterface();
|
||||
glInterface.reset(GrGLCreateNativeInterface());
|
||||
break;
|
||||
#if SK_ANGLE
|
||||
case kANGLE_DeviceType:
|
||||
fCurIntf = GrGLCreateANGLEInterface();
|
||||
glInterface.reset(GrGLCreateANGLEInterface());
|
||||
break;
|
||||
#endif // SK_ANGLE
|
||||
case kNullGPU_DeviceType:
|
||||
fCurIntf = GrGLCreateNullInterface();
|
||||
glInterface.reset(GrGLCreateNullInterface());
|
||||
break;
|
||||
default:
|
||||
SkASSERT(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Currently SampleApp does not use NVPR. TODO: Provide an NVPR device type that is skipped
|
||||
// when the driver doesn't support NVPR.
|
||||
fCurIntf = GrGLInterfaceRemoveNVPR(glInterface.get());
|
||||
|
||||
SkASSERT(NULL == fCurContext);
|
||||
fCurContext = GrContext::Create(kOpenGL_GrBackend, (GrBackendContext) fCurIntf);
|
||||
|
||||
@ -239,6 +244,8 @@ public:
|
||||
// We need some context and interface to see results
|
||||
SkSafeUnref(fCurContext);
|
||||
SkSafeUnref(fCurIntf);
|
||||
fCurContext = NULL;
|
||||
fCurIntf = NULL;
|
||||
SkDebugf("Failed to setup 3D");
|
||||
|
||||
win->detach();
|
||||
|
@ -309,8 +309,7 @@ void GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
|
||||
// attachment, hence this min:
|
||||
fMaxRenderTargetSize = GrMin(fMaxTextureSize, fMaxRenderTargetSize);
|
||||
|
||||
fPathRenderingSupport = GR_GL_USE_NV_PATH_RENDERING &&
|
||||
ctxInfo.hasExtension("GL_NV_path_rendering");
|
||||
fPathRenderingSupport = ctxInfo.hasExtension("GL_NV_path_rendering");
|
||||
SkASSERT(!fPathRenderingSupport || fFixedFunctionSupport);
|
||||
|
||||
fDstReadInShaderSupport = kNone_FBFetchType != fFBFetchType;
|
||||
|
@ -12,12 +12,35 @@
|
||||
#include "SkTSearch.h"
|
||||
#include "SkTSort.h"
|
||||
|
||||
namespace {
|
||||
namespace { // This cannot be static because it is used as a template parameter.
|
||||
inline bool extension_compare(const SkString& a, const SkString& b) {
|
||||
return strcmp(a.c_str(), b.c_str()) < 0;
|
||||
}
|
||||
}
|
||||
|
||||
// finds the index of ext in strings or a negative result if ext is not found.
|
||||
static int find_string(const SkTArray<SkString>& strings, const char ext[]) {
|
||||
if (strings.empty()) {
|
||||
return -1;
|
||||
}
|
||||
SkString extensionStr(ext);
|
||||
int idx = SkTSearch<SkString, extension_compare>(&strings.front(),
|
||||
strings.count(),
|
||||
extensionStr,
|
||||
sizeof(SkString));
|
||||
return idx;
|
||||
}
|
||||
|
||||
GrGLExtensions::GrGLExtensions(const GrGLExtensions& that) : fStrings(SkNEW(SkTArray<SkString>)) {
|
||||
*this = that;
|
||||
}
|
||||
|
||||
GrGLExtensions& GrGLExtensions::operator=(const GrGLExtensions& that) {
|
||||
*fStrings = *that.fStrings;
|
||||
fInitialized = that.fInitialized;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool GrGLExtensions::init(GrGLStandard standard,
|
||||
GrGLGetStringProc getString,
|
||||
GrGLGetStringiProc getStringi,
|
||||
@ -76,16 +99,25 @@ bool GrGLExtensions::init(GrGLStandard standard,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrGLExtensions::has(const char* ext) const {
|
||||
if (fStrings->empty()) {
|
||||
bool GrGLExtensions::has(const char ext[]) const {
|
||||
SkASSERT(fInitialized);
|
||||
return find_string(*fStrings, ext) >= 0;
|
||||
}
|
||||
|
||||
bool GrGLExtensions::remove(const char ext[]) {
|
||||
SkASSERT(fInitialized);
|
||||
int idx = find_string(*fStrings, ext);
|
||||
if (idx >= 0) {
|
||||
// This is not terribly effecient but we really only expect this function to be called at
|
||||
// most a handful of times when our test programs start.
|
||||
SkAutoTDelete< SkTArray<SkString> > oldStrings(fStrings.detach());
|
||||
fStrings.reset(SkNEW(SkTArray<SkString>(oldStrings->count() - 1)));
|
||||
fStrings->push_back_n(idx, &oldStrings->front());
|
||||
fStrings->push_back_n(oldStrings->count() - idx - 1, &(*oldStrings)[idx] + 1);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
SkString extensionStr(ext);
|
||||
int idx = SkTSearch<SkString, extension_compare>(&fStrings->front(),
|
||||
fStrings->count(),
|
||||
extensionStr,
|
||||
sizeof(SkString));
|
||||
return idx >= 0;
|
||||
}
|
||||
|
||||
void GrGLExtensions::print(const char* sep) const {
|
||||
|
@ -18,6 +18,64 @@ void GrGLDefaultInterfaceCallback(const GrGLInterface*) {}
|
||||
}
|
||||
#endif
|
||||
|
||||
const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) {
|
||||
GrGLInterface* newInterface = GrGLInterface::NewClone(interface);
|
||||
|
||||
newInterface->fExtensions.remove("GL_NV_path_rendering");
|
||||
|
||||
newInterface->fPathCommands = NULL;
|
||||
newInterface->fPathCoords = NULL;
|
||||
newInterface->fPathSubCommands = NULL;
|
||||
newInterface->fPathSubCoords = NULL;
|
||||
newInterface->fPathString = NULL;
|
||||
newInterface->fPathGlyphs = NULL;
|
||||
newInterface->fPathGlyphRange = NULL;
|
||||
newInterface->fWeightPaths = NULL;
|
||||
newInterface->fCopyPath = NULL;
|
||||
newInterface->fInterpolatePaths = NULL;
|
||||
newInterface->fTransformPath = NULL;
|
||||
newInterface->fPathParameteriv = NULL;
|
||||
newInterface->fPathParameteri = NULL;
|
||||
newInterface->fPathParameterfv = NULL;
|
||||
newInterface->fPathParameterf = NULL;
|
||||
newInterface->fPathDashArray = NULL;
|
||||
newInterface->fGenPaths = NULL;
|
||||
newInterface->fDeletePaths = NULL;
|
||||
newInterface->fIsPath = NULL;
|
||||
newInterface->fPathStencilFunc = NULL;
|
||||
newInterface->fPathStencilDepthOffset = NULL;
|
||||
newInterface->fStencilFillPath = NULL;
|
||||
newInterface->fStencilStrokePath = NULL;
|
||||
newInterface->fStencilFillPathInstanced = NULL;
|
||||
newInterface->fStencilStrokePathInstanced = NULL;
|
||||
newInterface->fPathCoverDepthFunc = NULL;
|
||||
newInterface->fPathColorGen = NULL;
|
||||
newInterface->fPathTexGen = NULL;
|
||||
newInterface->fPathFogGen = NULL;
|
||||
newInterface->fCoverFillPath = NULL;
|
||||
newInterface->fCoverStrokePath = NULL;
|
||||
newInterface->fCoverFillPathInstanced = NULL;
|
||||
newInterface->fCoverStrokePathInstanced = NULL;
|
||||
newInterface->fGetPathParameteriv = NULL;
|
||||
newInterface->fGetPathParameterfv = NULL;
|
||||
newInterface->fGetPathCommands = NULL;
|
||||
newInterface->fGetPathCoords = NULL;
|
||||
newInterface->fGetPathDashArray = NULL;
|
||||
newInterface->fGetPathMetrics = NULL;
|
||||
newInterface->fGetPathMetricRange = NULL;
|
||||
newInterface->fGetPathSpacing = NULL;
|
||||
newInterface->fGetPathColorGeniv = NULL;
|
||||
newInterface->fGetPathColorGenfv = NULL;
|
||||
newInterface->fGetPathTexGeniv = NULL;
|
||||
newInterface->fGetPathTexGenfv = NULL;
|
||||
newInterface->fIsPointInFillPath = NULL;
|
||||
newInterface->fIsPointInStrokePath = NULL;
|
||||
newInterface->fGetPathLength = NULL;
|
||||
newInterface->fPointAlongPath = NULL;
|
||||
|
||||
return newInterface;
|
||||
}
|
||||
|
||||
GrGLInterface::GrGLInterface()
|
||||
// TODO: Remove this madness ASAP.
|
||||
: fActiveTexture(&fFunctions.fActiveTexture)
|
||||
@ -205,8 +263,7 @@ GrGLInterface::GrGLInterface()
|
||||
, fIsPointInFillPath(&fFunctions.fIsPointInFillPath)
|
||||
, fIsPointInStrokePath(&fFunctions.fIsPointInStrokePath)
|
||||
, fGetPathLength(&fFunctions.fGetPathLength)
|
||||
, fPointAlongPath(&fFunctions.fPointAlongPath)
|
||||
{
|
||||
, fPointAlongPath(&fFunctions.fPointAlongPath) {
|
||||
fStandard = kNone_GrGLStandard;
|
||||
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
@ -215,6 +272,20 @@ GrGLInterface::GrGLInterface()
|
||||
#endif
|
||||
}
|
||||
|
||||
GrGLInterface* GrGLInterface::NewClone(const GrGLInterface* interface) {
|
||||
SkASSERT(NULL != interface);
|
||||
|
||||
GrGLInterface* clone = SkNEW(GrGLInterface);
|
||||
clone->fStandard = interface->fStandard;
|
||||
clone->fExtensions = interface->fExtensions;
|
||||
clone->fFunctions = interface->fFunctions;
|
||||
#if GR_GL_PER_GL_FUNC_CALLBACK
|
||||
clone->fCallback = interface->fCallback;
|
||||
clone->fCallbackData = interface->fCallbackData;
|
||||
#endif
|
||||
return clone;
|
||||
}
|
||||
|
||||
bool GrGLInterface::validate() const {
|
||||
|
||||
if (kNone_GrGLStandard == fStandard) {
|
||||
@ -405,7 +476,7 @@ bool GrGLInterface::validate() const {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (false && fExtensions.has("GL_NV_path_rendering")) {
|
||||
if (fExtensions.has("GL_NV_path_rendering")) {
|
||||
if (NULL == fFunctions.fPathCommands ||
|
||||
NULL == fFunctions.fPathCoords ||
|
||||
NULL == fFunctions.fPathSubCommands ||
|
||||
|
@ -152,5 +152,10 @@ const GrGLInterface* GrGLCreateANGLEInterface() {
|
||||
|
||||
functions->fMapBuffer = (GrGLMapBufferProc) eglGetProcAddress("glMapBufferOES");
|
||||
functions->fUnmapBuffer = (GrGLUnmapBufferProc) eglGetProcAddress("glUnmapBufferOES");
|
||||
|
||||
interface->fExtensions.init(kGLES_GrGLStandard,
|
||||
interface->fFunctions.fGetString,
|
||||
interface->fFunctions.fGetStringi,
|
||||
interface->fFunctions.fGetIntegerv);
|
||||
return interface;
|
||||
}
|
||||
|
@ -86,10 +86,8 @@ const GrGLInterface* SkNativeGLContext::createGLContext() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// We don't want the core profile when using NV path rendering (since
|
||||
// NV path rendering relies on fixed function calls)
|
||||
if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0,
|
||||
!GR_GL_USE_NV_PATH_RENDERING))) {
|
||||
// Requesting a Core profile would bar us from using NVPR. So we pass false.
|
||||
if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false))) {
|
||||
SkDebugf("Could not create rendering context.\n");
|
||||
this->destroyGLContext();
|
||||
return NULL;
|
||||
|
@ -18,6 +18,16 @@ DEF_GPUTEST(GLInterfaceValidation, reporter, factory) {
|
||||
// this forces the factory to make the context if it hasn't yet
|
||||
factory->get(glCtxType);
|
||||
SkGLContextHelper* glCtxHelper = factory->getGLContext(glCtxType);
|
||||
|
||||
// We're supposed to fail the NVPR context type when we the native context that does not
|
||||
// support the NVPR extension.
|
||||
if (GrContextFactory::kNVPR_GLContextType == glCtxType &&
|
||||
NULL != factory->getGLContext(GrContextFactory::kNative_GLContextType) &&
|
||||
!factory->getGLContext(GrContextFactory::kNative_GLContextType)->hasExtension("GL_NV_path_rendering")) {
|
||||
REPORTER_ASSERT(reporter, NULL == glCtxHelper);
|
||||
continue;
|
||||
}
|
||||
|
||||
REPORTER_ASSERT(reporter, NULL != glCtxHelper);
|
||||
if (NULL != glCtxHelper) {
|
||||
const GrGLInterface* interface = glCtxHelper->gl();
|
||||
|
Loading…
Reference in New Issue
Block a user