Refactor separable varying location info to be stored in GrGLProgram subclass
Refactor separable varying location info to be stored in GrGLProgram subclass GrGLProgram instead of storing it in GrGLPathProcessor. Separable varyings are exactly analoguous to uniforms: they are inputs to the shader program. Shader compile-time information about uniforms is gathered to GrGLProgramBuilder. This information is the converted to link-time information, uniform locations, when constructing the program. Separable varyings need to have same lifetime model. This is needed in the future to support path rendering in Chromium. The Chromium pseudo-extension will expose program fragment input binding function similar to uniform binding function. Thus the separable varying locations need to be decided and bound before link, e.g. before GrGLProgram is created. This will be achieved in further patches by overloading GrGLProgramBuilder::bindProgramResourceLocations() in GrGLNvprProgramBuilder. BUG=chromium:344330 Review URL: https://codereview.chromium.org/1186113007
This commit is contained in:
parent
e04edd8c86
commit
7aedda57f8
@ -295,6 +295,10 @@
|
||||
'<(skia_src_path)/gpu/gl/GrGLNameAllocator.h',
|
||||
'<(skia_src_path)/gpu/gl/GrGLNoOpInterface.cpp',
|
||||
'<(skia_src_path)/gpu/gl/GrGLNoOpInterface.h',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPathProgram.cpp',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPathProgram.h',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPathProgramDataManager.cpp',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPathProgramDataManager.h',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPath.cpp',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPath.h',
|
||||
'<(skia_src_path)/gpu/gl/GrGLPathProcessor.cpp',
|
||||
@ -331,6 +335,8 @@
|
||||
'<(skia_src_path)/gpu/gl/GrGLXferProcessor.h',
|
||||
|
||||
# Files for building GLSL shaders
|
||||
'<(skia_src_path)/gpu/gl/builders/GrGLPathProgramBuilder.cpp',
|
||||
'<(skia_src_path)/gpu/gl/builders/GrGLPathProgramBuilder.h',
|
||||
'<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.cpp',
|
||||
'<(skia_src_path)/gpu/gl/builders/GrGLProgramBuilder.h',
|
||||
'<(skia_src_path)/gpu/gl/builders/GrGLShaderBuilder.cpp',
|
||||
|
@ -71,16 +71,11 @@ void GrGLPathProcessor::emitTransforms(GrGLGPBuilder* pb, const TransformsIn& ti
|
||||
coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
|
||||
kVec2f_GrSLType;
|
||||
|
||||
|
||||
SkString strVaryingName("MatrixCoord");
|
||||
strVaryingName.appendf("_%i_%i", i, t);
|
||||
GrGLVertToFrag v(varyingType);
|
||||
pb->addVarying(strVaryingName.c_str(), &v);
|
||||
SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back();
|
||||
varyingInfo.fVariable = pb->getFragmentShaderBuilder()->fInputs.back();
|
||||
varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1;
|
||||
varyingInfo.fType = varyingType;
|
||||
fInstalledTransforms[i][t].fHandle = ShaderVarHandle(varyingInfo.fLocation);
|
||||
fInstalledTransforms[i][t].fHandle =
|
||||
pb->addSeparableVarying(strVaryingName.c_str(), &v).toShaderBuilderIndex();
|
||||
fInstalledTransforms[i][t].fType = varyingType;
|
||||
|
||||
SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords,
|
||||
@ -89,25 +84,11 @@ void GrGLPathProcessor::emitTransforms(GrGLGPBuilder* pb, const TransformsIn& ti
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLPathProcessor::resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) {
|
||||
int count = fSeparableVaryingInfos.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GrGLint location;
|
||||
GR_GL_CALL_RET(gpu->glInterface(),
|
||||
location,
|
||||
GetProgramResourceLocation(programId,
|
||||
GR_GL_FRAGMENT_INPUT,
|
||||
fSeparableVaryingInfos[i].fVariable.c_str()));
|
||||
fSeparableVaryingInfos[i].fLocation = location;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLPathProcessor::setTransformData(
|
||||
const GrPrimitiveProcessor& primProc,
|
||||
const GrGLPathProgramDataManager& pdman,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& coordTransforms,
|
||||
GrGLPathRendering* glpr,
|
||||
GrGLuint programID) {
|
||||
const SkTArray<const GrCoordTransform*, true>& coordTransforms) {
|
||||
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
|
||||
SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
|
||||
int numTransforms = transforms.count();
|
||||
@ -119,15 +100,10 @@ void GrGLPathProcessor::setTransformData(
|
||||
continue;
|
||||
}
|
||||
transforms[t].fCurrentValue = transform;
|
||||
const SeparableVaryingInfo& fragmentInput =
|
||||
fSeparableVaryingInfos[transforms[t].fHandle.handle()];
|
||||
|
||||
SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
|
||||
transforms[t].fType == kVec3f_GrSLType);
|
||||
unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
|
||||
glpr->setProgramPathFragmentInputTransform(programID,
|
||||
fragmentInput.fLocation,
|
||||
GR_GL_OBJECT_LINEAR,
|
||||
components,
|
||||
transform);
|
||||
pdman.setPathFragmentInputTransform(transforms[t].fHandle.handle(), components, transform);
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
class GrPathProcessor;
|
||||
class GrGLPathRendering;
|
||||
class GrGLGpu;
|
||||
class GrGLPathProgramDataManager;
|
||||
|
||||
class GrGLPathProcessor : public GrGLPrimitiveProcessor {
|
||||
public:
|
||||
@ -27,6 +28,7 @@ public:
|
||||
|
||||
void emitTransforms(GrGLGPBuilder*, const TransformsIn&, TransformsOut*);
|
||||
|
||||
void bindSeparableVaryings(GrGLGpu* gpu, GrGLuint programID);
|
||||
void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId);
|
||||
|
||||
void setData(const GrGLProgramDataManager&,
|
||||
@ -34,25 +36,15 @@ public:
|
||||
const GrBatchTracker&) override;
|
||||
|
||||
void setTransformData(const GrPrimitiveProcessor&,
|
||||
const GrGLPathProgramDataManager&,
|
||||
int index,
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms,
|
||||
GrGLPathRendering*,
|
||||
GrGLuint programID);
|
||||
const SkTArray<const GrCoordTransform*, true>& transforms);
|
||||
|
||||
virtual void didSetData(GrGLPathRendering*) {}
|
||||
|
||||
private:
|
||||
UniformHandle fColorUniform;
|
||||
GrColor fColor;
|
||||
struct SeparableVaryingInfo {
|
||||
GrSLType fType;
|
||||
GrGLShaderVar fVariable;
|
||||
GrGLint fLocation;
|
||||
};
|
||||
|
||||
typedef SkSTArray<8, SeparableVaryingInfo, true> SeparableVaryingInfoArray;
|
||||
|
||||
SeparableVaryingInfoArray fSeparableVaryingInfos;
|
||||
|
||||
typedef GrGLPrimitiveProcessor INHERITED;
|
||||
};
|
||||
|
52
src/gpu/gl/GrGLPathProgram.cpp
Normal file
52
src/gpu/gl/GrGLPathProgram.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrGLPathProgram.h"
|
||||
#include "GrGLPathProcessor.h"
|
||||
#include "GrGLGpu.h"
|
||||
#include "GrPathProcessor.h"
|
||||
|
||||
GrGLPathProgram::GrGLPathProgram(GrGLGpu* gpu,
|
||||
const GrProgramDesc& desc,
|
||||
const BuiltinUniformHandles& builtinUniforms,
|
||||
GrGLuint programID,
|
||||
const UniformInfoArray& uniforms,
|
||||
const SeparableVaryingInfoArray& separableVaryings,
|
||||
GrGLInstalledGeoProc* primProc,
|
||||
GrGLInstalledXferProc* xferProcessor,
|
||||
GrGLInstalledFragProcs* fragmentProcessors,
|
||||
SkTArray<UniformHandle>* passSamplerUniforms)
|
||||
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc,
|
||||
xferProcessor, fragmentProcessors, passSamplerUniforms)
|
||||
, fPathProgramDataManager(gpu, fProgramID, separableVaryings) {
|
||||
}
|
||||
void GrGLPathProgram::didSetData() {
|
||||
GrGLPathProcessor* pathProc =
|
||||
static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
|
||||
pathProc->didSetData(fGpu->glPathRendering());
|
||||
}
|
||||
|
||||
void GrGLPathProgram::setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrPendingFragmentStage& proc,
|
||||
int index,
|
||||
GrGLInstalledFragProc* ip) {
|
||||
GrGLPathProcessor* pathProc =
|
||||
static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
|
||||
pathProc->setTransformData(primProc, fPathProgramDataManager, index,
|
||||
proc.processor()->coordTransforms());
|
||||
}
|
||||
|
||||
void GrGLPathProgram::onSetRenderTargetState(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline) {
|
||||
SkASSERT(!primProc.willUseGeoShader() && primProc.numAttribs() == 0);
|
||||
const GrRenderTarget* rt = pipeline.getRenderTarget();
|
||||
SkISize size;
|
||||
size.set(rt->width(), rt->height());
|
||||
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
|
||||
fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
|
||||
size, rt->origin());
|
||||
}
|
49
src/gpu/gl/GrGLPathProgram.h
Normal file
49
src/gpu/gl/GrGLPathProgram.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrGLPathProgram_DEFINED
|
||||
#define GrGLPathProgram_DEFINED
|
||||
|
||||
#include "gl/GrGLProgram.h"
|
||||
#include "gl/GrGLPathProgramDataManager.h"
|
||||
|
||||
/*
|
||||
* The default GrGL programs consist of at the very least a vertex and fragment shader.
|
||||
* 1.3+ Nvpr ignores the vertex shader, but both require
|
||||
* specialized methods for setting transform data. NVPR also requires setting the
|
||||
* projection matrix through a special function call.
|
||||
*/
|
||||
class GrGLPathProgram : public GrGLProgram {
|
||||
protected:
|
||||
typedef GrGLPathProgramDataManager::SeparableVaryingInfoArray SeparableVaryingInfoArray;
|
||||
GrGLPathProgram(GrGLGpu*,
|
||||
const GrProgramDesc&,
|
||||
const BuiltinUniformHandles&,
|
||||
GrGLuint programID,
|
||||
const UniformInfoArray&,
|
||||
const SeparableVaryingInfoArray&,
|
||||
GrGLInstalledGeoProc*,
|
||||
GrGLInstalledXferProc* xferProcessor,
|
||||
GrGLInstalledFragProcs* fragmentProcessors,
|
||||
SkTArray<UniformHandle>* passSamplerUniforms);
|
||||
|
||||
private:
|
||||
void didSetData() override;
|
||||
virtual void setTransformData(const GrPrimitiveProcessor&,
|
||||
const GrPendingFragmentStage&,
|
||||
int index,
|
||||
GrGLInstalledFragProc*) override;
|
||||
virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
|
||||
|
||||
friend class GrGLPathProgramBuilder;
|
||||
|
||||
GrGLPathProgramDataManager fPathProgramDataManager;
|
||||
|
||||
typedef GrGLProgram INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
48
src/gpu/gl/GrGLPathProgramDataManager.cpp
Normal file
48
src/gpu/gl/GrGLPathProgramDataManager.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gl/GrGLPathProgramDataManager.h"
|
||||
#include "gl/GrGLPathRendering.h"
|
||||
#include "gl/GrGLUniformHandle.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "SkMatrix.h"
|
||||
|
||||
GrGLPathProgramDataManager::GrGLPathProgramDataManager(
|
||||
GrGLGpu* gpu, GrGLuint programID, const SeparableVaryingInfoArray& separableVaryings)
|
||||
: fGpu(gpu)
|
||||
, fProgramID(programID) {
|
||||
int count = separableVaryings.count();
|
||||
fSeparableVaryings.push_back_n(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
SeparableVarying& separableVarying = fSeparableVaryings[i];
|
||||
const SeparableVaryingInfo& builderSeparableVarying = separableVaryings[i];
|
||||
SkASSERT(GrGLShaderVar::kNonArray == builderSeparableVarying.fVariable.getArrayCount() ||
|
||||
builderSeparableVarying.fVariable.getArrayCount() > 0);
|
||||
SkDEBUGCODE(
|
||||
separableVarying.fArrayCount = builderSeparableVarying.fVariable.getArrayCount();
|
||||
separableVarying.fType = builderSeparableVarying.fVariable.getType();
|
||||
);
|
||||
separableVarying.fLocation = builderSeparableVarying.fLocation;
|
||||
}
|
||||
}
|
||||
|
||||
void GrGLPathProgramDataManager::setPathFragmentInputTransform(SeparableVaryingHandle u,
|
||||
int components,
|
||||
const SkMatrix& matrix) const {
|
||||
const SeparableVarying& fragmentInput =
|
||||
fSeparableVaryings[u.toProgramDataIndex()];
|
||||
|
||||
SkASSERT((components == 2 && fragmentInput.fType == kVec2f_GrSLType) ||
|
||||
(components == 3 && fragmentInput.fType == kVec3f_GrSLType));
|
||||
|
||||
fGpu->glPathRendering()->setProgramPathFragmentInputTransform(fProgramID,
|
||||
fragmentInput.fLocation,
|
||||
GR_GL_OBJECT_LINEAR,
|
||||
components,
|
||||
matrix);
|
||||
}
|
||||
|
75
src/gpu/gl/GrGLPathProgramDataManager.h
Normal file
75
src/gpu/gl/GrGLPathProgramDataManager.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#ifndef GrGLPathProgramDataManager_DEFINED
|
||||
#define GrGLPathProgramDataManager_DEFINED
|
||||
|
||||
#include "gl/GrGLProgramDataManager.h"
|
||||
|
||||
class GrGLPathProgram;
|
||||
class GrGLPathProgramBuilder;
|
||||
|
||||
/** Manages the resources used by a shader program for NVPR rendering.
|
||||
*/
|
||||
class GrGLPathProgramDataManager : SkNoncopyable {
|
||||
public:
|
||||
class SeparableVaryingHandle : public GrGLProgramDataManager::ShaderResourceHandle {
|
||||
public:
|
||||
/*
|
||||
* Creates a reference to a separable varying of a GrGLShaderBuilder. The ref can be used
|
||||
* to set the varying with the corresponding GrGLPathProgramDataManager.
|
||||
*/
|
||||
static SeparableVaryingHandle CreateFromSeparableVaryingIndex(int i) {
|
||||
return GrGLPathProgramDataManager::SeparableVaryingHandle(i);
|
||||
}
|
||||
SeparableVaryingHandle() { }
|
||||
bool operator==(const SeparableVaryingHandle& other) {
|
||||
return other.fValue == fValue;
|
||||
}
|
||||
private:
|
||||
SeparableVaryingHandle(int value) : ShaderResourceHandle(value) { }
|
||||
int toProgramDataIndex() const { SkASSERT(isValid()); return fValue; }
|
||||
int toShaderBuilderIndex() const { return toProgramDataIndex(); }
|
||||
|
||||
friend class GrGLPathProgramDataManager; // For accessing toProgramDataIndex().
|
||||
friend class GrGLPathProcessor; // For accessing toShaderBuilderIndex().
|
||||
};
|
||||
|
||||
struct SeparableVaryingInfo {
|
||||
GrGLShaderVar fVariable;
|
||||
GrGLint fLocation;
|
||||
};
|
||||
|
||||
// This uses an allocator rather than array so that the GrGLShaderVars don't move in memory
|
||||
// after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their
|
||||
// name strings. Otherwise, we'd have to hand out copies.
|
||||
typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray;
|
||||
|
||||
GrGLPathProgramDataManager(GrGLGpu*, GrGLuint programID, const SeparableVaryingInfoArray&);
|
||||
|
||||
/** Functions for uploading the varying values.
|
||||
*/
|
||||
void setPathFragmentInputTransform(SeparableVaryingHandle u,
|
||||
int components,
|
||||
const SkMatrix& matrix) const;
|
||||
private:
|
||||
enum {
|
||||
kUnusedSeparableVarying = -1,
|
||||
};
|
||||
struct SeparableVarying {
|
||||
GrGLint fLocation;
|
||||
SkDEBUGCODE(
|
||||
GrSLType fType;
|
||||
int fArrayCount;
|
||||
);
|
||||
};
|
||||
SkTArray<SeparableVarying, true> fSeparableVaryings;
|
||||
GrGLGpu* fGpu;
|
||||
GrGLuint fProgramID;
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
#endif
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "GrPrimitiveProcessor.h"
|
||||
#include "GrGLProcessor.h"
|
||||
#include "GrGLPathProgramDataManager.h"
|
||||
|
||||
class GrBatchTracker;
|
||||
class GrPrimitiveProcessor;
|
||||
@ -20,6 +21,7 @@ public:
|
||||
virtual ~GrGLPrimitiveProcessor() {}
|
||||
|
||||
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
|
||||
typedef GrGLPathProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
|
||||
typedef GrGLProcessor::TextureSamplerArray TextureSamplerArray;
|
||||
|
||||
typedef SkSTArray<2, const GrCoordTransform*, true> ProcCoords;
|
||||
@ -85,6 +87,10 @@ protected:
|
||||
SkASSERT(this->isValid());
|
||||
return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fHandle);
|
||||
}
|
||||
SeparableVaryingHandle convertToSeparableVaryingHandle() {
|
||||
SkASSERT(this->isValid());
|
||||
return SeparableVaryingHandle::CreateFromSeparableVaryingIndex(fHandle);
|
||||
}
|
||||
|
||||
private:
|
||||
int fHandle;
|
||||
|
@ -155,43 +155,3 @@ void GrGLProgram::onSetRenderTargetState(const GrPrimitiveProcessor&,
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrGLNvprProgram::GrGLNvprProgram(GrGLGpu* gpu,
|
||||
const GrProgramDesc& desc,
|
||||
const BuiltinUniformHandles& builtinUniforms,
|
||||
GrGLuint programID,
|
||||
const UniformInfoArray& uniforms,
|
||||
GrGLInstalledGeoProc* primProc,
|
||||
GrGLInstalledXferProc* xferProcessor,
|
||||
GrGLInstalledFragProcs* fragmentProcessors,
|
||||
SkTArray<UniformHandle>* passSamplerUniforms)
|
||||
: INHERITED(gpu, desc, builtinUniforms, programID, uniforms, primProc,
|
||||
xferProcessor, fragmentProcessors, passSamplerUniforms) {
|
||||
}
|
||||
void GrGLNvprProgram::didSetData() {
|
||||
GrGLPathProcessor* pathProc =
|
||||
static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
|
||||
pathProc->didSetData(fGpu->glPathRendering());
|
||||
}
|
||||
|
||||
void GrGLNvprProgram::setTransformData(const GrPrimitiveProcessor& primProc,
|
||||
const GrPendingFragmentStage& proc,
|
||||
int index,
|
||||
GrGLInstalledFragProc* ip) {
|
||||
GrGLPathProcessor* pathProc =
|
||||
static_cast<GrGLPathProcessor*>(fGeometryProcessor.get()->fGLProc.get());
|
||||
pathProc->setTransformData(primProc, index, proc.processor()->coordTransforms(),
|
||||
fGpu->glPathRendering(), fProgramID);
|
||||
}
|
||||
|
||||
void GrGLNvprProgram::onSetRenderTargetState(const GrPrimitiveProcessor& primProc,
|
||||
const GrPipeline& pipeline) {
|
||||
SkASSERT(!primProc.willUseGeoShader() && primProc.numAttribs() == 0);
|
||||
const GrRenderTarget* rt = pipeline.getRenderTarget();
|
||||
SkISize size;
|
||||
size.set(rt->width(), rt->height());
|
||||
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
|
||||
fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
|
||||
size, rt->origin());
|
||||
}
|
||||
|
@ -152,36 +152,4 @@ protected:
|
||||
typedef SkRefCnt INHERITED;
|
||||
};
|
||||
|
||||
/*
|
||||
* Below are slight specializations of the program object for the different types of programs
|
||||
* The default GrGL programs consist of at the very least a vertex and fragment shader.
|
||||
* Legacy Nvpr only has a fragment shader, 1.3+ Nvpr ignores the vertex shader, but both require
|
||||
* specialized methods for setting transform data. Both types of NVPR also require setting the
|
||||
* projection matrix through a special function call
|
||||
*/
|
||||
class GrGLNvprProgram : public GrGLProgram {
|
||||
protected:
|
||||
GrGLNvprProgram(GrGLGpu*,
|
||||
const GrProgramDesc&,
|
||||
const BuiltinUniformHandles&,
|
||||
GrGLuint programID,
|
||||
const UniformInfoArray&,
|
||||
GrGLInstalledGeoProc*,
|
||||
GrGLInstalledXferProc* xferProcessor,
|
||||
GrGLInstalledFragProcs* fragmentProcessors,
|
||||
SkTArray<UniformHandle>* passSamplerUniforms);
|
||||
|
||||
private:
|
||||
void didSetData() override;
|
||||
virtual void setTransformData(const GrPrimitiveProcessor&,
|
||||
const GrPendingFragmentStage&,
|
||||
int index,
|
||||
GrGLInstalledFragProc*) override;
|
||||
virtual void onSetRenderTargetState(const GrPrimitiveProcessor&, const GrPipeline&);
|
||||
|
||||
friend class GrGLNvprProgramBuilder;
|
||||
|
||||
typedef GrGLProgram INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -5,7 +5,7 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "gl/GrGLPathRendering.h"
|
||||
#include "gl/GrGLProgramDataManager.h"
|
||||
#include "gl/GrGLUniformHandle.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "SkMatrix.h"
|
||||
|
50
src/gpu/gl/builders/GrGLPathProgramBuilder.cpp
Normal file
50
src/gpu/gl/builders/GrGLPathProgramBuilder.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "GrGLPathProgramBuilder.h"
|
||||
#include "gl/GrGLGpu.h"
|
||||
#include "gl/GrGLPathProgram.h"
|
||||
|
||||
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
|
||||
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
|
||||
|
||||
GrGLPathProgramBuilder::GrGLPathProgramBuilder(GrGLGpu* gpu, const DrawArgs& args)
|
||||
: INHERITED(gpu, args)
|
||||
, fSeparableVaryingInfos(kVarsPerBlock) {
|
||||
}
|
||||
|
||||
GrGLProgram* GrGLPathProgramBuilder::createProgram(GrGLuint programID) {
|
||||
return SkNEW_ARGS(GrGLPathProgram, (fGpu, this->desc(), fUniformHandles, programID,
|
||||
fUniforms,
|
||||
fSeparableVaryingInfos,
|
||||
fGeometryProcessor,
|
||||
fXferProcessor, fFragmentProcessors.get(),
|
||||
&fSamplerUniforms));
|
||||
}
|
||||
|
||||
GrGLProgramBuilder::SeparableVaryingHandle GrGLPathProgramBuilder::addSeparableVarying(
|
||||
const char* name, GrGLVertToFrag* v, GrSLPrecision fsPrecision) {
|
||||
this->addVarying(name, v, fsPrecision);
|
||||
SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back();
|
||||
varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back();
|
||||
varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1;
|
||||
return SeparableVaryingHandle::CreateFromSeparableVaryingIndex(varyingInfo.fLocation);
|
||||
}
|
||||
|
||||
void GrGLPathProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) {
|
||||
this->INHERITED::resolveProgramResourceLocations(programID);
|
||||
|
||||
int count = fSeparableVaryingInfos.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GrGLint location;
|
||||
GL_CALL_RET(location,
|
||||
GetProgramResourceLocation(programID,
|
||||
GR_GL_FRAGMENT_INPUT,
|
||||
fSeparableVaryingInfos[i].fVariable.c_str()));
|
||||
fSeparableVaryingInfos[i].fLocation = location;
|
||||
}
|
||||
}
|
31
src/gpu/gl/builders/GrGLPathProgramBuilder.h
Normal file
31
src/gpu/gl/builders/GrGLPathProgramBuilder.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
#ifndef GrGLPathProgramBuilder_DEFINED
|
||||
#define GrGLPathProgramBuilder_DEFINED
|
||||
|
||||
#include "GrGLProgramBuilder.h"
|
||||
|
||||
class GrGLPathProgramBuilder : public GrGLProgramBuilder {
|
||||
public:
|
||||
GrGLPathProgramBuilder(GrGLGpu* gpu, const DrawArgs& args);
|
||||
|
||||
GrGLProgram* createProgram(GrGLuint programID) override;
|
||||
|
||||
SeparableVaryingHandle addSeparableVarying(const char* name, GrGLVertToFrag* v,
|
||||
GrSLPrecision fsPrecision) override;
|
||||
void resolveProgramResourceLocations(GrGLuint programID) override;
|
||||
|
||||
private:
|
||||
typedef GrGLPathProgramDataManager::SeparableVaryingInfo SeparableVaryingInfo;
|
||||
typedef GrGLPathProgramDataManager::SeparableVaryingInfoArray SeparableVaryingInfoArray;
|
||||
|
||||
SeparableVaryingInfoArray fSeparableVaryingInfos;
|
||||
|
||||
typedef GrGLProgramBuilder INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -17,6 +17,7 @@
|
||||
#include "glsl/GrGLSLCaps.h"
|
||||
#include "GrAutoLocaleSetter.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrGLPathProgramBuilder.h"
|
||||
#include "GrGLProgramBuilder.h"
|
||||
#include "GrTexture.h"
|
||||
#include "SkRTConf.h"
|
||||
@ -25,32 +26,6 @@
|
||||
#define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X)
|
||||
#define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class GrGLNvprProgramBuilder : public GrGLProgramBuilder {
|
||||
public:
|
||||
GrGLNvprProgramBuilder(GrGLGpu* gpu, const DrawArgs& args)
|
||||
: INHERITED(gpu, args) {}
|
||||
|
||||
GrGLProgram* createProgram(GrGLuint programID) override {
|
||||
// this is just for nvpr es, which has separable varyings that are plugged in after
|
||||
// building
|
||||
GrGLPathProcessor* pathProc =
|
||||
static_cast<GrGLPathProcessor*>(fGeometryProcessor->fGLProc.get());
|
||||
pathProc->resolveSeparableVaryings(fGpu, programID);
|
||||
return SkNEW_ARGS(GrGLNvprProgram, (fGpu, this->desc(), fUniformHandles, programID,
|
||||
fUniforms, fGeometryProcessor, fXferProcessor,
|
||||
fFragmentProcessors.get(), &fSamplerUniforms));
|
||||
}
|
||||
|
||||
private:
|
||||
typedef GrGLProgramBuilder INHERITED;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const int GrGLProgramBuilder::kVarsPerBlock = 8;
|
||||
|
||||
GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gpu) {
|
||||
@ -80,7 +55,7 @@ GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg
|
||||
SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() &&
|
||||
!args.fPrimitiveProcessor->willUseGeoShader() &&
|
||||
args.fPrimitiveProcessor->numAttribs() == 0);
|
||||
return SkNEW_ARGS(GrGLNvprProgramBuilder, (gpu, args));
|
||||
return SkNEW_ARGS(GrGLPathProgramBuilder, (gpu, args));
|
||||
} else {
|
||||
return SkNEW_ARGS(GrGLProgramBuilder, (gpu, args));
|
||||
}
|
||||
@ -126,6 +101,18 @@ void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att
|
||||
fFS.codeAppendf("%s = %s;", output, v.fsIn());
|
||||
}
|
||||
|
||||
GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVarying(const char*,
|
||||
GrGLVertToFrag*,
|
||||
GrSLPrecision) {
|
||||
// This call is not used for non-NVPR backends. However, the polymorphism between
|
||||
// GrPrimitiveProcessor, GrGLPrimitiveProcessor and GrGLProgramBuilder does not allow for
|
||||
// a system where GrGLPathProcessor would be able to refer to a primitive-specific builder
|
||||
// that would understand separable varyings. Thus separable varyings need to be present
|
||||
// early in the inheritance chain of builders.
|
||||
SkASSERT(false);
|
||||
return SeparableVaryingHandle();
|
||||
}
|
||||
|
||||
void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) {
|
||||
if ('\0' == prefix) {
|
||||
*out = name;
|
||||
@ -423,11 +410,8 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
|
||||
if (usingBindUniform) {
|
||||
this->bindUniformLocations(programID);
|
||||
}
|
||||
fFS.bindFragmentShaderLocations(programID);
|
||||
this->bindProgramResourceLocations(programID);
|
||||
|
||||
GL_CALL(LinkProgram(programID));
|
||||
|
||||
// Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
|
||||
@ -438,21 +422,24 @@ GrGLProgram* GrGLProgramBuilder::finalize() {
|
||||
if (checkLinked) {
|
||||
checkLinkStatus(programID);
|
||||
}
|
||||
if (!usingBindUniform) {
|
||||
this->resolveUniformLocations(programID);
|
||||
}
|
||||
this->resolveProgramResourceLocations(programID);
|
||||
|
||||
this->cleanupShaders(shadersToDelete);
|
||||
|
||||
return this->createProgram(programID);
|
||||
}
|
||||
|
||||
void GrGLProgramBuilder::bindUniformLocations(GrGLuint programID) {
|
||||
int count = fUniforms.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
|
||||
fUniforms[i].fLocation = i;
|
||||
void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) {
|
||||
bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
|
||||
if (usingBindUniform) {
|
||||
int count = fUniforms.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_str()));
|
||||
fUniforms[i].fLocation = i;
|
||||
}
|
||||
}
|
||||
|
||||
fFS.bindFragmentShaderLocations(programID);
|
||||
}
|
||||
|
||||
bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
|
||||
@ -479,12 +466,15 @@ bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) {
|
||||
return SkToBool(linked);
|
||||
}
|
||||
|
||||
void GrGLProgramBuilder::resolveUniformLocations(GrGLuint programID) {
|
||||
int count = fUniforms.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GrGLint location;
|
||||
GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
|
||||
fUniforms[i].fLocation = location;
|
||||
void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) {
|
||||
bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation != NULL;
|
||||
if (!usingBindUniform) {
|
||||
int count = fUniforms.count();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
GrGLint location;
|
||||
GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVariable.c_str()));
|
||||
fUniforms[i].fLocation = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "GrGLGeometryShaderBuilder.h"
|
||||
#include "GrGLVertexShaderBuilder.h"
|
||||
#include "../GrGLProgramDataManager.h"
|
||||
#include "../GrGLPathProgramDataManager.h"
|
||||
#include "../GrGLUniformHandle.h"
|
||||
#include "../GrGLPrimitiveProcessor.h"
|
||||
#include "../GrGLXferProcessor.h"
|
||||
@ -39,6 +40,7 @@ public:
|
||||
virtual ~GrGLUniformBuilder() {}
|
||||
|
||||
typedef GrGLProgramDataManager::UniformHandle UniformHandle;
|
||||
typedef GrGLPathProgramDataManager::SeparableVaryingHandle SeparableVaryingHandle;
|
||||
|
||||
/** Add a uniform variable to the current program, that has visibility in one or more shaders.
|
||||
visibility is a bitfield of ShaderVisibility values indicating from which shaders the
|
||||
@ -154,6 +156,13 @@ public:
|
||||
virtual void addPassThroughAttribute(const GrGeometryProcessor::Attribute*,
|
||||
const char* output) = 0;
|
||||
|
||||
/*
|
||||
* Creates a fragment shader varying that can be referred to.
|
||||
* Comparable to GrGLUniformBuilder::addUniform().
|
||||
*/
|
||||
virtual SeparableVaryingHandle addSeparableVarying(
|
||||
const char* name, GrGLVertToFrag*, GrSLPrecision fsPrecision = kDefault_GrSLPrecision) = 0;
|
||||
|
||||
// TODO rename getFragmentBuilder
|
||||
virtual GrGLFragmentBuilder* getFragmentShaderBuilder() = 0;
|
||||
virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0;
|
||||
@ -252,6 +261,10 @@ public:
|
||||
void addPassThroughAttribute(const GrPrimitiveProcessor::Attribute*,
|
||||
const char* output) override;
|
||||
|
||||
SeparableVaryingHandle addSeparableVarying(
|
||||
const char* name,
|
||||
GrGLVertToFrag*,
|
||||
GrSLPrecision fsPrecision = kDefault_GrSLPrecision) override;
|
||||
|
||||
// Handles for program uniforms (other than per-effect uniforms)
|
||||
struct BuiltinUniformHandles {
|
||||
@ -315,9 +328,9 @@ protected:
|
||||
GrGLInstalledProc<Proc>*);
|
||||
|
||||
GrGLProgram* finalize();
|
||||
void bindUniformLocations(GrGLuint programID);
|
||||
void bindProgramResourceLocations(GrGLuint programID);
|
||||
bool checkLinkStatus(GrGLuint programID);
|
||||
void resolveUniformLocations(GrGLuint programID);
|
||||
virtual void resolveProgramResourceLocations(GrGLuint programID);
|
||||
void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs);
|
||||
void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs);
|
||||
|
||||
|
@ -203,5 +203,6 @@ protected:
|
||||
bool fFinalized;
|
||||
|
||||
friend class GrGLProgramBuilder;
|
||||
friend class GrGLPathProgramBuilder; // to access fInputs.
|
||||
};
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user