From eeef46d181f9f8db388ecea81df699fc1b3c9280 Mon Sep 17 00:00:00 2001 From: kkinnunen Date: Thu, 2 Jul 2015 03:01:43 -0700 Subject: Implement support for CHROMIUM_path_rendering pseudo extension Implement support for path rendering in Chromium through CHROMIUM_path_rendering pseudo extension. The extension defines a new pseudo-gl function, BindFragmentInputLocation. This behaves similarly to the BindUniformLocation pseudo-gl function. The idea is to assign fragment input location to a fragment input before linking the program. BUG=chromium:344330 Review URL: https://codereview.chromium.org/1192663002 --- src/gpu/gl/GrGLCaps.cpp | 8 ++++++-- src/gpu/gl/GrGLInterface.cpp | 8 +++++++- src/gpu/gl/GrGLPathRendering.cpp | 3 +++ src/gpu/gl/GrGLPathRendering.h | 12 ++++++++++++ src/gpu/gl/builders/GrGLPathProgramBuilder.cpp | 18 +++++++++++++++++- src/gpu/gl/builders/GrGLPathProgramBuilder.h | 1 + src/gpu/gl/builders/GrGLProgramBuilder.h | 2 +- 7 files changed, 47 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 539212c3a5..dc0cf2cd59 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -464,16 +464,20 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, } bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { - if (!ctxInfo.hasExtension("GL_NV_path_rendering")) { + bool hasChromiumPathRendering = ctxInfo.hasExtension("GL_CHROMIUM_path_rendering"); + + if (!(ctxInfo.hasExtension("GL_NV_path_rendering") || hasChromiumPathRendering)) { 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)) { + if (!hasChromiumPathRendering && + ctxInfo.version() < GR_GL_VER(3, 1)) { return false; } } diff --git a/src/gpu/gl/GrGLInterface.cpp b/src/gpu/gl/GrGLInterface.cpp index 56f1e59275..9f58c73221 100644 --- a/src/gpu/gl/GrGLInterface.cpp +++ b/src/gpu/gl/GrGLInterface.cpp @@ -59,6 +59,7 @@ const GrGLInterface* GrGLInterfaceRemoveNVPR(const GrGLInterface* interface) { newInterface->fFunctions.fStencilThenCoverFillPathInstanced = NULL; newInterface->fFunctions.fStencilThenCoverStrokePathInstanced = NULL; newInterface->fFunctions.fProgramPathFragmentInputGen = NULL; + newInterface->fFunctions.fBindFragmentInputLocation = NULL; return newInterface; } @@ -483,7 +484,7 @@ bool GrGLInterface::validate() const { #endif } - if (fExtensions.has("GL_NV_path_rendering")) { + if (fExtensions.has("GL_NV_path_rendering") || fExtensions.has("GL_CHROMIUM_path_rendering")) { if (NULL == fFunctions.fMatrixLoadf || NULL == fFunctions.fMatrixLoadIdentity || NULL == fFunctions.fPathCommands || @@ -515,6 +516,11 @@ bool GrGLInterface::validate() const { ) { RETURN_FALSE_INTERFACE } + if (fExtensions.has("GL_CHROMIUM_path_rendering")) { + if (NULL == fFunctions.fBindFragmentInputLocation) { + 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 ffdbbdab26..7c77155b6c 100644 --- a/src/gpu/gl/GrGLPathRendering.cpp +++ b/src/gpu/gl/GrGLPathRendering.cpp @@ -61,6 +61,9 @@ 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.bindFragmentInputSupport = + NULL != glInterface->fFunctions.fBindFragmentInputLocation; } GrGLPathRendering::~GrGLPathRendering() { diff --git a/src/gpu/gl/GrGLPathRendering.h b/src/gpu/gl/GrGLPathRendering.h index 86cf1b1698..5996e906bd 100644 --- a/src/gpu/gl/GrGLPathRendering.h +++ b/src/gpu/gl/GrGLPathRendering.h @@ -46,6 +46,10 @@ public: */ void abandonGpuResources(); + bool shouldBindFragmentInputs() const { + return fCaps.bindFragmentInputSupport; + } + // Functions for "separable shader" texturing support. void setProgramPathFragmentInputTransform(GrGLuint program, GrGLint location, GrGLenum genMode, GrGLint components, @@ -65,6 +69,13 @@ 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. + */ + struct Caps { + bool bindFragmentInputSupport : 1; + }; + void flushPathStencilSettings(const GrStencilSettings&); struct MatrixState { @@ -103,6 +114,7 @@ private: SkAutoTDelete fPathNameAllocator; MatrixState fHWProjectionMatrixState; GrStencilSettings fHWPathStencilSettings; + Caps fCaps; }; #endif diff --git a/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp b/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp index c9f88cd702..9bebe0d89e 100644 --- a/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLPathProgramBuilder.cpp @@ -35,9 +35,25 @@ GrGLProgramBuilder::SeparableVaryingHandle GrGLPathProgramBuilder::addSeparableV return SeparableVaryingHandle::CreateFromSeparableVaryingIndex(varyingInfo.fLocation); } +void GrGLPathProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { + this->INHERITED::bindProgramResourceLocations(programID); + if (!fGpu->glPathRendering()->shouldBindFragmentInputs()) { + return; + } + int count = fSeparableVaryingInfos.count(); + for (int i = 0; i < count; ++i) { + GL_CALL(BindFragmentInputLocation(programID, + i, + fSeparableVaryingInfos[i].fVariable.c_str())); + fSeparableVaryingInfos[i].fLocation = i; + } +} + void GrGLPathProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { this->INHERITED::resolveProgramResourceLocations(programID); - + if (fGpu->glPathRendering()->shouldBindFragmentInputs()) { + return; + } int count = fSeparableVaryingInfos.count(); for (int i = 0; i < count; ++i) { GrGLint location; diff --git a/src/gpu/gl/builders/GrGLPathProgramBuilder.h b/src/gpu/gl/builders/GrGLPathProgramBuilder.h index 28260cf760..d0c77fcdc7 100644 --- a/src/gpu/gl/builders/GrGLPathProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLPathProgramBuilder.h @@ -17,6 +17,7 @@ public: SeparableVaryingHandle addSeparableVarying(const char* name, GrGLVertToFrag* v, GrSLPrecision fsPrecision) override; + void bindProgramResourceLocations(GrGLuint programID) override; void resolveProgramResourceLocations(GrGLuint programID) override; private: diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 4b784aceea..22b67ae58d 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -328,7 +328,7 @@ protected: GrGLInstalledProc*); GrGLProgram* finalize(); - void bindProgramResourceLocations(GrGLuint programID); + virtual void bindProgramResourceLocations(GrGLuint programID); bool checkLinkStatus(GrGLuint programID); virtual void resolveProgramResourceLocations(GrGLuint programID); void cleanupProgram(GrGLuint programID, const SkTDArray& shaderIDs); -- cgit v1.2.3