Delete pre-glop path

bug:19014311

Change-Id: I06376b6f625455892d8eafe2727b78025a64c4bf
This commit is contained in:
Chris Craik
2015-04-03 09:37:49 -07:00
parent 095d999045
commit 828407356d
7 changed files with 221 additions and 2013 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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