Delete pre-glop path
bug:19014311 Change-Id: I06376b6f625455892d8eafe2727b78025a64c4bf
This commit is contained in:
@@ -46,51 +46,11 @@ namespace uirenderer {
|
||||
// blur inputs smaller than this constant will bypass renderscript
|
||||
#define RS_MIN_INPUT_CUTOFF 10000
|
||||
|
||||
#define USE_GLOPS true
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// TextSetupFunctor
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void TextSetupFunctor::setup(GLenum glyphFormat) {
|
||||
renderer->setupDraw();
|
||||
renderer->setupDrawTextGamma(paint);
|
||||
renderer->setupDrawDirtyRegionsDisabled();
|
||||
renderer->setupDrawWithTexture(glyphFormat == GL_ALPHA);
|
||||
switch (glyphFormat) {
|
||||
case GL_ALPHA: {
|
||||
renderer->setupDrawAlpha8Color(paint->getColor(), alpha);
|
||||
break;
|
||||
}
|
||||
case GL_RGBA: {
|
||||
float floatAlpha = alpha / 255.0f;
|
||||
renderer->setupDrawColor(floatAlpha, floatAlpha, floatAlpha, floatAlpha);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
#if DEBUG_FONT_RENDERER
|
||||
ALOGD("TextSetupFunctor: called with unknown glyph format %x", glyphFormat);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
renderer->setupDrawColorFilter(paint->getColorFilter());
|
||||
renderer->setupDrawShader(paint->getShader());
|
||||
renderer->setupDrawBlending(paint);
|
||||
renderer->setupDrawProgram();
|
||||
renderer->setupDrawModelView(kModelViewMode_Translate, false,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, pureTranslate);
|
||||
// Calling setupDrawTexture with the name 0 will enable the
|
||||
// uv attributes and increase the texture unit count
|
||||
// texture binding will be performed by the font renderer as
|
||||
// needed
|
||||
renderer->setupDrawTexture(0);
|
||||
renderer->setupDrawPureColorUniforms();
|
||||
renderer->setupDrawColorFilterUniforms(paint->getColorFilter());
|
||||
renderer->setupDrawShaderUniforms(paint->getShader(), pureTranslate);
|
||||
renderer->setupDrawTextGammaUniforms();
|
||||
}
|
||||
|
||||
void TextSetupFunctor::draw(CacheTexture& texture, bool linearFiltering) {
|
||||
void TextDrawFunctor::draw(CacheTexture& texture, bool linearFiltering) {
|
||||
int textureFillFlags = static_cast<int>(texture.getFormat() == GL_ALPHA
|
||||
? TextureFillFlags::kIsAlphaMaskTexture : TextureFillFlags::kNone);
|
||||
if (linearFiltering) {
|
||||
@@ -508,11 +468,6 @@ void FontRenderer::checkTextureUpdate() {
|
||||
void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) {
|
||||
if (!mFunctor) return;
|
||||
|
||||
#if !USE_GLOPS
|
||||
Caches& caches = mFunctor->renderer->getCaches();
|
||||
RenderState& renderState = mFunctor->renderer->renderState();
|
||||
#endif
|
||||
|
||||
bool first = true;
|
||||
bool forceRebind = false;
|
||||
for (uint32_t i = 0; i < cacheTextures.size(); i++) {
|
||||
@@ -520,37 +475,12 @@ void FontRenderer::issueDrawCommand(Vector<CacheTexture*>& cacheTextures) {
|
||||
if (texture->canDraw()) {
|
||||
if (first) {
|
||||
checkTextureUpdate();
|
||||
#if !USE_GLOPS
|
||||
mFunctor->setup(texture->getFormat());
|
||||
|
||||
renderState.meshState().bindQuadIndicesBuffer();
|
||||
|
||||
// If returns true, a VBO was bound and we must
|
||||
// rebind our vertex attrib pointers even if
|
||||
// they have the same values as the current pointers
|
||||
forceRebind = renderState.meshState().unbindMeshBuffer();
|
||||
|
||||
caches.textureState().activateTexture(0);
|
||||
#endif
|
||||
first = false;
|
||||
mDrawn = true;
|
||||
}
|
||||
#if USE_GLOPS
|
||||
|
||||
mFunctor->draw(*texture, mLinearFiltering);
|
||||
#endif
|
||||
|
||||
#if !USE_GLOPS
|
||||
caches.textureState().bindTexture(texture->getTextureId());
|
||||
texture->setLinearFiltering(mLinearFiltering);
|
||||
|
||||
TextureVertex* mesh = texture->mesh();
|
||||
MeshState& meshState = renderState.meshState();
|
||||
meshState.bindPositionVertexPointer(forceRebind, &mesh[0].x);
|
||||
meshState.bindTexCoordsVertexPointer(forceRebind, &mesh[0].u);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, texture->meshElementCount(),
|
||||
GL_UNSIGNED_SHORT, texture->indices());
|
||||
#endif
|
||||
texture->resetMesh();
|
||||
forceRebind = false;
|
||||
}
|
||||
@@ -689,7 +619,7 @@ FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, co
|
||||
return image;
|
||||
}
|
||||
|
||||
void FontRenderer::initRender(const Rect* clip, Rect* bounds, TextSetupFunctor* functor) {
|
||||
void FontRenderer::initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor) {
|
||||
checkInit();
|
||||
|
||||
mDrawn = false;
|
||||
@@ -717,7 +647,7 @@ void FontRenderer::endPrecaching() {
|
||||
|
||||
bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
|
||||
uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y,
|
||||
const float* positions, Rect* bounds, TextSetupFunctor* functor, bool forceFinish) {
|
||||
const float* positions, Rect* bounds, TextDrawFunctor* functor, bool forceFinish) {
|
||||
if (!mCurrentFont) {
|
||||
ALOGE("No font set");
|
||||
return false;
|
||||
@@ -735,7 +665,7 @@ bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const c
|
||||
|
||||
bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
|
||||
uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path,
|
||||
float hOffset, float vOffset, Rect* bounds, TextSetupFunctor* functor) {
|
||||
float hOffset, float vOffset, Rect* bounds, TextDrawFunctor* functor) {
|
||||
if (!mCurrentFont) {
|
||||
ALOGE("No font set");
|
||||
return false;
|
||||
|
||||
@@ -46,9 +46,9 @@ namespace uirenderer {
|
||||
|
||||
class OpenGLRenderer;
|
||||
|
||||
class TextSetupFunctor {
|
||||
class TextDrawFunctor {
|
||||
public:
|
||||
TextSetupFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate,
|
||||
TextDrawFunctor(OpenGLRenderer* renderer, float x, float y, bool pureTranslate,
|
||||
int alpha, SkXfermode::Mode mode, const SkPaint* paint)
|
||||
: renderer(renderer)
|
||||
, x(x)
|
||||
@@ -59,8 +59,6 @@ public:
|
||||
, paint(paint) {
|
||||
}
|
||||
|
||||
void setup(GLenum glyphFormat);
|
||||
|
||||
void draw(CacheTexture& texture, bool linearFiltering);
|
||||
|
||||
OpenGLRenderer* renderer;
|
||||
@@ -92,12 +90,12 @@ public:
|
||||
// bounds is an out parameter
|
||||
bool renderPosText(const SkPaint* paint, const Rect* clip, const char *text,
|
||||
uint32_t startIndex, uint32_t len, int numGlyphs, int x, int y, const float* positions,
|
||||
Rect* bounds, TextSetupFunctor* functor, bool forceFinish = true);
|
||||
Rect* bounds, TextDrawFunctor* functor, bool forceFinish = true);
|
||||
|
||||
// bounds is an out parameter
|
||||
bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const char *text,
|
||||
uint32_t startIndex, uint32_t len, int numGlyphs, const SkPath* path,
|
||||
float hOffset, float vOffset, Rect* bounds, TextSetupFunctor* functor);
|
||||
float hOffset, float vOffset, Rect* bounds, TextDrawFunctor* functor);
|
||||
|
||||
struct DropShadow {
|
||||
uint32_t width;
|
||||
@@ -135,7 +133,7 @@ private:
|
||||
void flushAllAndInvalidate();
|
||||
|
||||
void checkInit();
|
||||
void initRender(const Rect* clip, Rect* bounds, TextSetupFunctor* functor);
|
||||
void initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor);
|
||||
void finishRender();
|
||||
|
||||
void issueDrawCommand(Vector<CacheTexture*>& cacheTextures);
|
||||
@@ -176,7 +174,7 @@ private:
|
||||
|
||||
bool mUploadTexture;
|
||||
|
||||
TextSetupFunctor* mFunctor;
|
||||
TextDrawFunctor* mFunctor;
|
||||
const Rect* mClip;
|
||||
Rect* mBounds;
|
||||
bool mDrawn;
|
||||
|
||||
@@ -586,6 +586,12 @@ void GlopBuilder::build() {
|
||||
mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kColor;
|
||||
mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha;
|
||||
|
||||
// Enable debug highlight when what we're about to draw is tested against
|
||||
// the stencil buffer and if stencil highlight debugging is on
|
||||
mDescription.hasDebugHighlight = !mCaches.debugOverdraw
|
||||
&& mCaches.debugStencilClip == Caches::kStencilShowHighlight
|
||||
&& mRenderState.stencil().isTestEnabled();
|
||||
|
||||
// serialize shader info into ShaderData
|
||||
GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0;
|
||||
SkiaShader::store(mCaches, mShader, mOutGlop->transform.modelView,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -65,7 +65,7 @@ class DeferredDisplayState;
|
||||
struct Glop;
|
||||
class RenderState;
|
||||
class RenderNode;
|
||||
class TextSetupFunctor;
|
||||
class TextDrawFunctor;
|
||||
class VertexBuffer;
|
||||
|
||||
struct DrawModifiers {
|
||||
@@ -726,15 +726,6 @@ private:
|
||||
*/
|
||||
void drawShape(float left, float top, PathTexture* texture, const SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Draws the specified texture as an alpha bitmap. Alpha bitmaps obey
|
||||
* different compositing rules.
|
||||
*
|
||||
* @param texture The texture to draw with
|
||||
* @param paint The paint to render with
|
||||
*/
|
||||
void drawAlphaBitmap(Texture* texture, const SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Renders a strip of polygons with the specified paint, used for tessellated geometry.
|
||||
*
|
||||
@@ -761,60 +752,6 @@ private:
|
||||
*/
|
||||
void drawConvexPath(const SkPath& path, const SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Draws a textured rectangle with the specified texture.
|
||||
*
|
||||
* @param texture The texture to use
|
||||
* @param paint The paint containing the alpha, blending mode, etc.
|
||||
*/
|
||||
void drawTextureRect(Texture* texture, const SkPaint* paint);
|
||||
|
||||
/**
|
||||
* Draws a textured mesh with the specified texture. If the indices are omitted,
|
||||
* the mesh is drawn as a simple quad. The mesh pointers become offsets when a
|
||||
* VBO is bound.
|
||||
*
|
||||
* @param left The left coordinate of the rectangle
|
||||
* @param top The top coordinate of the rectangle
|
||||
* @param right The right coordinate of the rectangle
|
||||
* @param bottom The bottom coordinate of the rectangle
|
||||
* @param texture The texture name to map onto the rectangle
|
||||
* @param paint The paint containing the alpha, blending mode, colorFilter, etc.
|
||||
* @param blend True if the texture contains an alpha channel
|
||||
* @param vertices The vertices that define the mesh
|
||||
* @param texCoords The texture coordinates of each vertex
|
||||
* @param elementsCount The number of elements in the mesh, required by indices
|
||||
* @param swapSrcDst Whether or not the src and dst blending operations should be swapped
|
||||
* @param ignoreTransform True if the current transform should be ignored
|
||||
* @param vbo The VBO used to draw the mesh
|
||||
* @param modelViewMode Defines whether the model view matrix should be scaled
|
||||
* @param dirty True if calling this method should dirty the current layer
|
||||
*/
|
||||
void drawTextureMesh(float left, float top, float right, float bottom, GLuint texture,
|
||||
const SkPaint* paint, bool blend,
|
||||
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
|
||||
bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
|
||||
ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
|
||||
|
||||
void drawIndexedTextureMesh(float left, float top, float right, float bottom, GLuint texture,
|
||||
const SkPaint* paint, bool blend,
|
||||
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
|
||||
bool swapSrcDst = false, bool ignoreTransform = false, GLuint vbo = 0,
|
||||
ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale, bool dirty = true);
|
||||
|
||||
void drawAlpha8TextureMesh(float left, float top, float right, float bottom,
|
||||
GLuint texture, const SkPaint* paint,
|
||||
GLvoid* vertices, GLvoid* texCoords, GLenum drawMode, GLsizei elementsCount,
|
||||
bool ignoreTransform, ModelViewMode modelViewMode = kModelViewMode_TranslateAndScale,
|
||||
bool dirty = true);
|
||||
|
||||
/**
|
||||
* Draws the specified list of vertices as quads using indexed GL_TRIANGLES.
|
||||
* If the number of vertices to draw exceeds the number of indices we have
|
||||
* pre-allocated, this method will generate several glDrawElements() calls.
|
||||
*/
|
||||
void issueIndexedQuadDraw(Vertex* mesh, GLsizei quadsCount);
|
||||
|
||||
/**
|
||||
* Draws text underline and strike-through if needed.
|
||||
*
|
||||
@@ -873,78 +810,6 @@ private:
|
||||
*/
|
||||
bool canSkipText(const SkPaint* paint) const;
|
||||
|
||||
/**
|
||||
* Enable or disable blending as necessary. This function sets the appropriate
|
||||
* blend function based on the specified xfermode.
|
||||
*/
|
||||
inline void chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description,
|
||||
bool swapSrcDst = false);
|
||||
|
||||
/**
|
||||
* Invoked before any drawing operation. This sets required state.
|
||||
*/
|
||||
void setupDraw(bool clear = true);
|
||||
|
||||
/**
|
||||
* Various methods to setup OpenGL rendering.
|
||||
*/
|
||||
void setupDrawWithTexture(bool isAlpha8 = false);
|
||||
void setupDrawWithTextureAndColor(bool isAlpha8 = false);
|
||||
void setupDrawWithExternalTexture();
|
||||
void setupDrawNoTexture();
|
||||
void setupDrawVertexAlpha(bool useShadowAlphaInterp);
|
||||
void setupDrawColor(int color, int alpha);
|
||||
void setupDrawColor(float r, float g, float b, float a);
|
||||
void setupDrawAlpha8Color(int color, int alpha);
|
||||
void setupDrawTextGamma(const SkPaint* paint);
|
||||
void setupDrawShader(const SkShader* shader);
|
||||
void setupDrawColorFilter(const SkColorFilter* filter);
|
||||
void setupDrawBlending(const Layer* layer, bool swapSrcDst = false);
|
||||
void setupDrawBlending(const SkPaint* paint, bool blend = true, bool swapSrcDst = false);
|
||||
void setupDrawProgram();
|
||||
void setupDrawDirtyRegionsDisabled();
|
||||
|
||||
/**
|
||||
* Setup the current program matrices based upon the nature of the geometry.
|
||||
*
|
||||
* @param mode If kModelViewMode_Translate, the geometry must be translated by the left and top
|
||||
* parameters. If kModelViewMode_TranslateAndScale, the geometry that exists in the (0,0, 1,1)
|
||||
* space must be scaled up and translated to fill the quad provided in (l,t,r,b). These
|
||||
* transformations are stored in the modelView matrix and uploaded to the shader.
|
||||
*
|
||||
* @param offset Set to true if the the matrix should be fudged (translated) slightly to
|
||||
* disambiguate geometry pixel positioning. See Vertex::GeometryFudgeFactor().
|
||||
*
|
||||
* @param ignoreTransform Set to true if l,t,r,b coordinates already in layer space,
|
||||
* currentTransform() will be ignored. (e.g. when drawing clip in layer coordinates to stencil,
|
||||
* or when simple translation has been extracted)
|
||||
*/
|
||||
void setupDrawModelView(ModelViewMode mode, bool offset,
|
||||
float left, float top, float right, float bottom, bool ignoreTransform = false);
|
||||
void setupDrawColorUniforms(bool hasShader);
|
||||
void setupDrawPureColorUniforms();
|
||||
|
||||
/**
|
||||
* Setup uniforms for the current shader.
|
||||
*
|
||||
* @param shader SkShader on the current paint.
|
||||
*
|
||||
* @param ignoreTransform Set to true to ignore the transform in shader.
|
||||
*/
|
||||
void setupDrawShaderUniforms(const SkShader* shader, bool ignoreTransform = false);
|
||||
void setupDrawColorFilterUniforms(const SkColorFilter* paint);
|
||||
void setupDrawSimpleMesh();
|
||||
void setupDrawTexture(GLuint texture);
|
||||
void setupDrawExternalTexture(GLuint texture);
|
||||
void setupDrawTextureTransform();
|
||||
void setupDrawTextureTransformUniforms(mat4& transform);
|
||||
void setupDrawTextGammaUniforms();
|
||||
void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords = nullptr, GLuint vbo = 0);
|
||||
void setupDrawMesh(const GLvoid* vertices, const GLvoid* texCoords, const GLvoid* colors);
|
||||
void setupDrawMeshIndices(const GLvoid* vertices, const GLvoid* texCoords, GLuint vbo = 0);
|
||||
void setupDrawIndexedVertices(GLvoid* vertices);
|
||||
void accountForClear(SkXfermode::Mode mode);
|
||||
|
||||
bool updateLayer(Layer* layer, bool inFrame);
|
||||
void updateLayers();
|
||||
void flushLayers();
|
||||
@@ -993,22 +858,6 @@ private:
|
||||
inline Snapshot* writableSnapshot() { return mState.writableSnapshot(); }
|
||||
inline const Snapshot* currentSnapshot() const { return mState.currentSnapshot(); }
|
||||
|
||||
/**
|
||||
* Model-view matrix used to position/size objects
|
||||
*
|
||||
* Stores operation-local modifications to the draw matrix that aren't incorporated into the
|
||||
* currentTransform().
|
||||
*
|
||||
* If generated with kModelViewMode_Translate, mModelViewMatrix will reflect an x/y offset,
|
||||
* e.g. the offset in drawLayer(). If generated with kModelViewMode_TranslateAndScale,
|
||||
* mModelViewMatrix will reflect a translation and scale, e.g. the translation and scale
|
||||
* required to make VBO 0 (a rect of (0,0,1,1)) scaled to match the x,y offset, and width/height
|
||||
* of a bitmap.
|
||||
*
|
||||
* Used as input to SkiaShader transformation.
|
||||
*/
|
||||
mat4 mModelViewMatrix;
|
||||
|
||||
// State used to define the clipping region
|
||||
Rect mTilingClip;
|
||||
// Is the target render surface opaque
|
||||
@@ -1016,9 +865,6 @@ private:
|
||||
// Is a frame currently being rendered
|
||||
bool mFrameStarted;
|
||||
|
||||
// Used to draw textured quads
|
||||
TextureVertex mMeshVertices[4];
|
||||
|
||||
// Default UV mapper
|
||||
const UvMapper mUvMapper;
|
||||
|
||||
@@ -1031,21 +877,6 @@ private:
|
||||
// List of layers to update at the beginning of a frame
|
||||
Vector< sp<Layer> > mLayerUpdates;
|
||||
|
||||
// The following fields are used to setup drawing
|
||||
// Used to describe the shaders to generate
|
||||
ProgramDescription mDescription;
|
||||
// Color description
|
||||
bool mColorSet;
|
||||
FloatColor mColor;
|
||||
// Indicates that the shader should get a color
|
||||
bool mSetShaderColor;
|
||||
// Current texture unit
|
||||
GLuint mTextureUnit;
|
||||
// Track dirty regions, true by default
|
||||
bool mTrackDirtyRegions;
|
||||
// Indicate whether we are drawing an opaque frame
|
||||
bool mOpaqueFrame;
|
||||
|
||||
// See PROPERTY_DISABLE_SCISSOR_OPTIMIZATION in
|
||||
// Properties.h
|
||||
bool mScissorOptimizationDisabled;
|
||||
@@ -1070,7 +901,7 @@ private:
|
||||
std::vector<std::unique_ptr<SkPath>> mTempPaths;
|
||||
|
||||
friend class Layer;
|
||||
friend class TextSetupFunctor;
|
||||
friend class TextDrawFunctor;
|
||||
friend class DrawBitmapOp;
|
||||
friend class DrawPatchOp;
|
||||
|
||||
|
||||
@@ -47,15 +47,6 @@ static inline bool isPowerOfTwo(unsigned int n) {
|
||||
return !(n & (n - 1));
|
||||
}
|
||||
|
||||
static inline void bindUniformColor(int slot, uint32_t color) {
|
||||
const float a = ((color >> 24) & 0xff) / 255.0f;
|
||||
glUniform4f(slot,
|
||||
a * ((color >> 16) & 0xff) / 255.0f,
|
||||
a * ((color >> 8) & 0xff) / 255.0f,
|
||||
a * ((color ) & 0xff) / 255.0f,
|
||||
a);
|
||||
}
|
||||
|
||||
static inline void bindUniformColor(int slot, FloatColor color) {
|
||||
glUniform4fv(slot, 1, reinterpret_cast<const float*>(&color));
|
||||
}
|
||||
@@ -83,229 +74,11 @@ static void computeScreenSpaceMatrix(mat4& screenSpace, const SkMatrix& unitMatr
|
||||
screenSpace.multiply(modelViewMatrix);
|
||||
}
|
||||
|
||||
// Returns true if one is a bitmap and the other is a gradient
|
||||
static bool bitmapAndGradient(SkiaShaderType type1, SkiaShaderType type2) {
|
||||
return (type1 == kBitmap_SkiaShaderType && type2 == kGradient_SkiaShaderType)
|
||||
|| (type2 == kBitmap_SkiaShaderType && type1 == kGradient_SkiaShaderType);
|
||||
}
|
||||
|
||||
SkiaShaderType SkiaShader::getType(const SkShader& shader) {
|
||||
// First check for a gradient shader.
|
||||
switch (shader.asAGradient(nullptr)) {
|
||||
case SkShader::kNone_GradientType:
|
||||
// Not a gradient shader. Fall through to check for other types.
|
||||
break;
|
||||
case SkShader::kLinear_GradientType:
|
||||
case SkShader::kRadial_GradientType:
|
||||
case SkShader::kSweep_GradientType:
|
||||
return kGradient_SkiaShaderType;
|
||||
default:
|
||||
// This is a Skia gradient that has no SkiaShader equivalent. Return None to skip.
|
||||
return kNone_SkiaShaderType;
|
||||
}
|
||||
|
||||
// The shader is not a gradient. Check for a bitmap shader.
|
||||
if (shader.asABitmap(nullptr, nullptr, nullptr) == SkShader::kDefault_BitmapType) {
|
||||
return kBitmap_SkiaShaderType;
|
||||
}
|
||||
|
||||
// Check for a ComposeShader.
|
||||
SkShader::ComposeRec rec;
|
||||
if (shader.asACompose(&rec)) {
|
||||
const SkiaShaderType shaderAType = getType(*rec.fShaderA);
|
||||
const SkiaShaderType shaderBType = getType(*rec.fShaderB);
|
||||
|
||||
// Compose is only supported if one is a bitmap and the other is a
|
||||
// gradient. Otherwise, return None to skip.
|
||||
if (!bitmapAndGradient(shaderAType, shaderBType)) {
|
||||
return kNone_SkiaShaderType;
|
||||
}
|
||||
return kCompose_SkiaShaderType;
|
||||
}
|
||||
|
||||
if (shader.asACustomShader(nullptr)) {
|
||||
return kLayer_SkiaShaderType;
|
||||
}
|
||||
|
||||
return kNone_SkiaShaderType;
|
||||
}
|
||||
|
||||
typedef void (*describeProc)(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader);
|
||||
|
||||
describeProc gDescribeProc[] = {
|
||||
InvalidSkiaShader::describe,
|
||||
SkiaBitmapShader::describe,
|
||||
SkiaGradientShader::describe,
|
||||
SkiaComposeShader::describe,
|
||||
SkiaLayerShader::describe,
|
||||
};
|
||||
|
||||
typedef void (*setupProgramProc)(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader);
|
||||
|
||||
setupProgramProc gSetupProgramProc[] = {
|
||||
InvalidSkiaShader::setupProgram,
|
||||
SkiaBitmapShader::setupProgram,
|
||||
SkiaGradientShader::setupProgram,
|
||||
SkiaComposeShader::setupProgram,
|
||||
SkiaLayerShader::setupProgram,
|
||||
};
|
||||
|
||||
void SkiaShader::describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader) {
|
||||
gDescribeProc[getType(shader)](caches, description, extensions, shader);
|
||||
}
|
||||
|
||||
void SkiaShader::setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) {
|
||||
|
||||
gSetupProgramProc[getType(shader)](caches, modelViewMatrix, textureUnit, extensions, shader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Layer shader
|
||||
// gradient shader matrix helpers
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkiaLayerShader::describe(Caches*, ProgramDescription& description,
|
||||
const Extensions&, const SkShader& shader) {
|
||||
description.hasBitmap = true;
|
||||
}
|
||||
|
||||
void SkiaLayerShader::setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions&, const SkShader& shader) {
|
||||
Layer* layer;
|
||||
if (!shader.asACustomShader(reinterpret_cast<void**>(&layer))) {
|
||||
LOG_ALWAYS_FATAL("SkiaLayerShader::setupProgram called on the wrong type of shader!");
|
||||
}
|
||||
|
||||
GLuint textureSlot = (*textureUnit)++;
|
||||
caches->textureState().activateTexture(textureSlot);
|
||||
|
||||
const float width = layer->getWidth();
|
||||
const float height = layer->getHeight();
|
||||
|
||||
mat4 textureTransform;
|
||||
computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(),
|
||||
modelViewMatrix);
|
||||
|
||||
|
||||
// Uniforms
|
||||
layer->bindTexture();
|
||||
layer->setWrap(GL_CLAMP_TO_EDGE);
|
||||
layer->setFilter(GL_LINEAR);
|
||||
|
||||
Program& program = caches->program();
|
||||
glUniform1i(program.getUniform("bitmapSampler"), textureSlot);
|
||||
glUniformMatrix4fv(program.getUniform("textureTransform"), 1,
|
||||
GL_FALSE, &textureTransform.data[0]);
|
||||
glUniform2f(program.getUniform("textureDimension"), 1.0f / width, 1.0f / height);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Bitmap shader
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct BitmapShaderInfo {
|
||||
float width;
|
||||
float height;
|
||||
GLenum wrapS;
|
||||
GLenum wrapT;
|
||||
Texture* texture;
|
||||
};
|
||||
|
||||
static bool bitmapShaderHelper(Caches* caches, ProgramDescription* description,
|
||||
BitmapShaderInfo* shaderInfo,
|
||||
const Extensions& extensions,
|
||||
const SkBitmap& bitmap, SkShader::TileMode tileModes[2]) {
|
||||
Texture* texture = caches->textureCache.get(&bitmap);
|
||||
if (!texture) return false;
|
||||
|
||||
const float width = texture->width;
|
||||
const float height = texture->height;
|
||||
GLenum wrapS, wrapT;
|
||||
|
||||
if (description) {
|
||||
description->hasBitmap = true;
|
||||
}
|
||||
// The driver does not support non-power of two mirrored/repeated
|
||||
// textures, so do it ourselves
|
||||
if (!extensions.hasNPot() && (!isPowerOfTwo(width) || !isPowerOfTwo(height)) &&
|
||||
(tileModes[0] != SkShader::kClamp_TileMode ||
|
||||
tileModes[1] != SkShader::kClamp_TileMode)) {
|
||||
if (description) {
|
||||
description->isBitmapNpot = true;
|
||||
description->bitmapWrapS = gTileModes[tileModes[0]];
|
||||
description->bitmapWrapT = gTileModes[tileModes[1]];
|
||||
}
|
||||
wrapS = GL_CLAMP_TO_EDGE;
|
||||
wrapT = GL_CLAMP_TO_EDGE;
|
||||
} else {
|
||||
wrapS = gTileModes[tileModes[0]];
|
||||
wrapT = gTileModes[tileModes[1]];
|
||||
}
|
||||
|
||||
if (shaderInfo) {
|
||||
shaderInfo->width = width;
|
||||
shaderInfo->height = height;
|
||||
shaderInfo->wrapS = wrapS;
|
||||
shaderInfo->wrapT = wrapT;
|
||||
shaderInfo->texture = texture;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SkiaBitmapShader::describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader) {
|
||||
SkBitmap bitmap;
|
||||
SkShader::TileMode xy[2];
|
||||
if (shader.asABitmap(&bitmap, nullptr, xy) != SkShader::kDefault_BitmapType) {
|
||||
LOG_ALWAYS_FATAL("SkiaBitmapShader::describe called with a different kind of shader!");
|
||||
}
|
||||
bitmapShaderHelper(caches, &description, nullptr, extensions, bitmap, xy);
|
||||
}
|
||||
|
||||
void SkiaBitmapShader::setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) {
|
||||
SkBitmap bitmap;
|
||||
SkShader::TileMode xy[2];
|
||||
if (shader.asABitmap(&bitmap, nullptr, xy) != SkShader::kDefault_BitmapType) {
|
||||
LOG_ALWAYS_FATAL("SkiaBitmapShader::setupProgram called with a different kind of shader!");
|
||||
}
|
||||
|
||||
GLuint textureSlot = (*textureUnit)++;
|
||||
caches->textureState().activateTexture(textureSlot);
|
||||
|
||||
BitmapShaderInfo shaderInfo;
|
||||
if (!bitmapShaderHelper(caches, nullptr, &shaderInfo, extensions, bitmap, xy)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Program& program = caches->program();
|
||||
Texture* texture = shaderInfo.texture;
|
||||
|
||||
const AutoTexture autoCleanup(texture);
|
||||
|
||||
mat4 textureTransform;
|
||||
computeScreenSpaceMatrix(textureTransform, SkMatrix::I(), shader.getLocalMatrix(),
|
||||
modelViewMatrix);
|
||||
|
||||
// Uniforms
|
||||
bindTexture(caches, texture, shaderInfo.wrapS, shaderInfo.wrapT);
|
||||
texture->setFilter(GL_LINEAR);
|
||||
|
||||
glUniform1i(program.getUniform("bitmapSampler"), textureSlot);
|
||||
glUniformMatrix4fv(program.getUniform("textureTransform"), 1,
|
||||
GL_FALSE, &textureTransform.data[0]);
|
||||
glUniform2f(program.getUniform("textureDimension"), 1.0f / shaderInfo.width,
|
||||
1.0f / shaderInfo.height);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Linear gradient shader
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) {
|
||||
static void toLinearUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) {
|
||||
SkVector vec = pts[1] - pts[0];
|
||||
const float mag = vec.length();
|
||||
const float inv = mag ? 1.0f / mag : 0;
|
||||
@@ -316,10 +89,6 @@ static void toUnitMatrix(const SkPoint pts[2], SkMatrix* matrix) {
|
||||
matrix->postScale(inv, inv);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Circular gradient shader
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void toCircularUnitMatrix(const float x, const float y, const float radius,
|
||||
SkMatrix* matrix) {
|
||||
const float inv = 1.0f / radius;
|
||||
@@ -327,10 +96,6 @@ static void toCircularUnitMatrix(const float x, const float y, const float radiu
|
||||
matrix->postScale(inv, inv);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Sweep gradient shader
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void toSweepUnitMatrix(const float x, const float y, SkMatrix* matrix) {
|
||||
matrix->setTranslate(-x, -y);
|
||||
}
|
||||
@@ -343,137 +108,6 @@ static bool isSimpleGradient(const SkShader::GradientInfo& gradInfo) {
|
||||
return gradInfo.fColorCount == 2 && gradInfo.fTileMode == SkShader::kClamp_TileMode;
|
||||
}
|
||||
|
||||
void SkiaGradientShader::describe(Caches*, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader) {
|
||||
SkShader::GradientInfo gradInfo;
|
||||
gradInfo.fColorCount = 0;
|
||||
gradInfo.fColors = nullptr;
|
||||
gradInfo.fColorOffsets = nullptr;
|
||||
|
||||
switch (shader.asAGradient(&gradInfo)) {
|
||||
case SkShader::kLinear_GradientType:
|
||||
description.gradientType = ProgramDescription::kGradientLinear;
|
||||
break;
|
||||
case SkShader::kRadial_GradientType:
|
||||
description.gradientType = ProgramDescription::kGradientCircular;
|
||||
break;
|
||||
case SkShader::kSweep_GradientType:
|
||||
description.gradientType = ProgramDescription::kGradientSweep;
|
||||
break;
|
||||
default:
|
||||
// Do nothing. This shader is unsupported.
|
||||
return;
|
||||
}
|
||||
description.hasGradient = true;
|
||||
description.isSimpleGradient = isSimpleGradient(gradInfo);
|
||||
}
|
||||
|
||||
void SkiaGradientShader::setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions&, const SkShader& shader) {
|
||||
// SkShader::GradientInfo.fColorCount is an in/out parameter. As input, it tells asAGradient
|
||||
// how much space has been allocated for fColors and fColorOffsets. 10 was chosen
|
||||
// arbitrarily, but should be >= 2.
|
||||
// As output, it tells the number of actual colors/offsets in the gradient.
|
||||
const int COLOR_COUNT = 10;
|
||||
SkAutoSTMalloc<COLOR_COUNT, SkColor> colorStorage(COLOR_COUNT);
|
||||
SkAutoSTMalloc<COLOR_COUNT, SkScalar> positionStorage(COLOR_COUNT);
|
||||
|
||||
SkShader::GradientInfo gradInfo;
|
||||
gradInfo.fColorCount = COLOR_COUNT;
|
||||
gradInfo.fColors = colorStorage.get();
|
||||
gradInfo.fColorOffsets = positionStorage.get();
|
||||
|
||||
SkShader::GradientType gradType = shader.asAGradient(&gradInfo);
|
||||
|
||||
Program& program = caches->program();
|
||||
if (CC_UNLIKELY(!isSimpleGradient(gradInfo))) {
|
||||
if (gradInfo.fColorCount > COLOR_COUNT) {
|
||||
// There was not enough room in our arrays for all the colors and offsets. Try again,
|
||||
// now that we know the true number of colors.
|
||||
gradInfo.fColors = colorStorage.reset(gradInfo.fColorCount);
|
||||
gradInfo.fColorOffsets = positionStorage.reset(gradInfo.fColorCount);
|
||||
|
||||
shader.asAGradient(&gradInfo);
|
||||
}
|
||||
GLuint textureSlot = (*textureUnit)++;
|
||||
caches->textureState().activateTexture(textureSlot);
|
||||
|
||||
#ifndef SK_SCALAR_IS_FLOAT
|
||||
#error Need to convert gradInfo.fColorOffsets to float!
|
||||
#endif
|
||||
Texture* texture = caches->gradientCache.get(gradInfo.fColors, gradInfo.fColorOffsets,
|
||||
gradInfo.fColorCount);
|
||||
|
||||
// Uniforms
|
||||
bindTexture(caches, texture, gTileModes[gradInfo.fTileMode], gTileModes[gradInfo.fTileMode]);
|
||||
glUniform1i(program.getUniform("gradientSampler"), textureSlot);
|
||||
} else {
|
||||
bindUniformColor(program.getUniform("startColor"), gradInfo.fColors[0]);
|
||||
bindUniformColor(program.getUniform("endColor"), gradInfo.fColors[1]);
|
||||
}
|
||||
|
||||
caches->dither.setupProgram(program, textureUnit);
|
||||
|
||||
SkMatrix unitMatrix;
|
||||
switch (gradType) {
|
||||
case SkShader::kLinear_GradientType:
|
||||
toUnitMatrix(gradInfo.fPoint, &unitMatrix);
|
||||
break;
|
||||
case SkShader::kRadial_GradientType:
|
||||
toCircularUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY,
|
||||
gradInfo.fRadius[0], &unitMatrix);
|
||||
break;
|
||||
case SkShader::kSweep_GradientType:
|
||||
toSweepUnitMatrix(gradInfo.fPoint[0].fX, gradInfo.fPoint[0].fY, &unitMatrix);
|
||||
break;
|
||||
default:
|
||||
LOG_ALWAYS_FATAL("Invalid SkShader gradient type %d", gradType);
|
||||
}
|
||||
|
||||
mat4 screenSpace;
|
||||
computeScreenSpaceMatrix(screenSpace, unitMatrix, shader.getLocalMatrix(), modelViewMatrix);
|
||||
glUniformMatrix4fv(program.getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Compose shader
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void SkiaComposeShader::describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader) {
|
||||
SkShader::ComposeRec rec;
|
||||
if (!shader.asACompose(&rec)) {
|
||||
LOG_ALWAYS_FATAL("SkiaComposeShader::describe called on the wrong shader type!");
|
||||
}
|
||||
SkiaShader::describe(caches, description, extensions, *rec.fShaderA);
|
||||
SkiaShader::describe(caches, description, extensions, *rec.fShaderB);
|
||||
if (SkiaShader::getType(*rec.fShaderA) == kBitmap_SkiaShaderType) {
|
||||
description.isBitmapFirst = true;
|
||||
}
|
||||
if (!SkXfermode::AsMode(rec.fMode, &description.shadersMode)) {
|
||||
// TODO: Support other modes.
|
||||
description.shadersMode = SkXfermode::kSrcOver_Mode;
|
||||
}
|
||||
}
|
||||
|
||||
void SkiaComposeShader::setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) {
|
||||
SkShader::ComposeRec rec;
|
||||
if (!shader.asACompose(&rec)) {
|
||||
LOG_ALWAYS_FATAL("SkiaComposeShader::setupProgram called on the wrong shader type!");
|
||||
}
|
||||
|
||||
// Apply this compose shader's local transform and pass it down to
|
||||
// the child shaders. They will in turn apply their local transform
|
||||
// to this matrix.
|
||||
mat4 transform;
|
||||
computeScreenSpaceMatrix(transform, SkMatrix::I(), shader.getLocalMatrix(),
|
||||
modelViewMatrix);
|
||||
|
||||
SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderA);
|
||||
SkiaShader::setupProgram(caches, transform, textureUnit, extensions, *rec.fShaderB);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Store / apply
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -491,7 +125,7 @@ bool tryStoreGradient(Caches& caches, const SkShader& shader, const Matrix4 mode
|
||||
case SkShader::kLinear_GradientType:
|
||||
description->gradientType = ProgramDescription::kGradientLinear;
|
||||
|
||||
toUnitMatrix(gradInfo.fPoint, &unitMatrix);
|
||||
toLinearUnitMatrix(gradInfo.fPoint, &unitMatrix);
|
||||
break;
|
||||
case SkShader::kRadial_GradientType:
|
||||
description->gradientType = ProgramDescription::kGradientCircular;
|
||||
|
||||
@@ -87,77 +87,12 @@ struct SkiaShaderData {
|
||||
|
||||
class SkiaShader {
|
||||
public:
|
||||
static SkiaShaderType getType(const SkShader& shader);
|
||||
static void describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader);
|
||||
static void setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader);
|
||||
|
||||
// new SkiaShader interaction model - store into ShaderData, and apply to Caches/Program/GL
|
||||
static void store(Caches& caches, const SkShader* shader, const Matrix4& modelViewMatrix,
|
||||
GLuint* textureUnit, ProgramDescription* description,
|
||||
SkiaShaderData* outData);
|
||||
static void apply(Caches& caches, const SkiaShaderData& data);
|
||||
};
|
||||
|
||||
class InvalidSkiaShader {
|
||||
public:
|
||||
static void describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader) {
|
||||
// This shader is unsupported. Skip it.
|
||||
}
|
||||
static void setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader) {
|
||||
// This shader is unsupported. Skip it.
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* A shader that draws a layer.
|
||||
*/
|
||||
class SkiaLayerShader {
|
||||
public:
|
||||
static void describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader);
|
||||
static void setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader);
|
||||
}; // class SkiaLayerShader
|
||||
|
||||
/**
|
||||
* A shader that draws a bitmap.
|
||||
*/
|
||||
class SkiaBitmapShader {
|
||||
public:
|
||||
static void describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader);
|
||||
static void setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader);
|
||||
|
||||
|
||||
}; // class SkiaBitmapShader
|
||||
|
||||
/**
|
||||
* A shader that draws one of three types of gradient, depending on shader param.
|
||||
*/
|
||||
class SkiaGradientShader {
|
||||
public:
|
||||
static void describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader);
|
||||
static void setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader);
|
||||
};
|
||||
|
||||
/**
|
||||
* A shader that draws two shaders, composited with an xfermode.
|
||||
*/
|
||||
class SkiaComposeShader {
|
||||
public:
|
||||
static void describe(Caches* caches, ProgramDescription& description,
|
||||
const Extensions& extensions, const SkShader& shader);
|
||||
static void setupProgram(Caches* caches, const mat4& modelViewMatrix,
|
||||
GLuint* textureUnit, const Extensions& extensions, const SkShader& shader);
|
||||
}; // class SkiaComposeShader
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
|
||||
Reference in New Issue
Block a user