Refactor Skia shaders handling.
With this change, Skia shaders can easily be applied to any mesh. This change also
supports ComposeShader. For instance, this can be used to blend a gradient and a
bitmap togehter and paint a string of text with the result.
Change-Id: I701c2f9cf7f89b2ff58005e8a1d0d80ccf4a4aea
diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h
new file mode 100644
index 0000000..b5e6aeb
--- /dev/null
+++ b/libs/hwui/SkiaShader.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SKIA_SHADER_H
+#define SKIA_SHADER_H
+
+#include <SkShader.h>
+#include <SkXfermode.h>
+
+#include <GLES2/gl2.h>
+
+#include "Extensions.h"
+#include "ProgramCache.h"
+#include "TextureCache.h"
+#include "GradientCache.h"
+#include "Snapshot.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Base shader
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Represents a Skia shader. A shader will modify the GL context and active
+ * program to recreate the original effect.
+ */
+struct SkiaShader {
+ /**
+ * Type of Skia shader in use.
+ */
+ enum Type {
+ kNone,
+ kBitmap,
+ kLinearGradient,
+ kCircularGradient,
+ kSweepGradient,
+ kCompose
+ };
+
+ SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, SkShader::TileMode tileY,
+ SkMatrix* matrix, bool blend);
+ virtual ~SkiaShader();
+
+ virtual void describe(ProgramDescription& description, const Extensions& extensions);
+ virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
+ GLuint* textureUnit);
+
+ inline bool blend() const {
+ return mBlend;
+ }
+
+ Type type() const {
+ return mType;
+ }
+
+ virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
+ mTextureCache = textureCache;
+ mGradientCache = gradientCache;
+ }
+
+ void setMatrix(SkMatrix* matrix) {
+ mMatrix = matrix;
+ }
+
+protected:
+ inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit);
+
+ Type mType;
+ SkShader* mKey;
+ SkShader::TileMode mTileX;
+ SkShader::TileMode mTileY;
+ SkMatrix* mMatrix;
+ bool mBlend;
+
+ TextureCache* mTextureCache;
+ GradientCache* mGradientCache;
+}; // struct SkiaShader
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Implementations
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A shader that draws a bitmap.
+ */
+struct SkiaBitmapShader: public SkiaShader {
+ SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX,
+ SkShader::TileMode tileY, SkMatrix* matrix, bool blend);
+ ~SkiaBitmapShader();
+
+ void describe(ProgramDescription& description, const Extensions& extensions);
+ void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
+ GLuint* textureUnit);
+
+private:
+ /**
+ * This method does not work for n == 0.
+ */
+ inline bool isPowerOfTwo(unsigned int n) {
+ return !(n & (n - 1));
+ }
+
+ SkBitmap* mBitmap;
+}; // struct SkiaBitmapShader
+
+/**
+ * A shader that draws a linear gradient.
+ */
+struct SkiaLinearGradientShader: public SkiaShader {
+ SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count,
+ SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
+ ~SkiaLinearGradientShader();
+
+ void describe(ProgramDescription& description, const Extensions& extensions);
+ void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
+ GLuint* textureUnit);
+
+private:
+ float* mBounds;
+ uint32_t* mColors;
+ float* mPositions;
+ int mCount;
+}; // struct SkiaLinearGradientShader
+
+/**
+ * A shader that draws two shaders, composited with an xfermode.
+ */
+struct SkiaComposeShader: public SkiaShader {
+ SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, SkShader* key);
+ ~SkiaComposeShader();
+
+ void set(TextureCache* textureCache, GradientCache* gradientCache);
+
+ void describe(ProgramDescription& description, const Extensions& extensions);
+ void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
+ GLuint* textureUnit);
+
+private:
+ SkiaShader* mFirst;
+ SkiaShader* mSecond;
+ SkXfermode::Mode mMode;
+}; // struct SkiaComposeShader
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // SKIA_SHADER_H