43ccf4663c
Change-Id: Ibbbd7146c5ff69e9639b433f39041053654d808c
265 lines
7.4 KiB
C++
265 lines
7.4 KiB
C++
/*
|
|
* 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 ANDROID_HWUI_SKIA_SHADER_H
|
|
#define ANDROID_HWUI_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 SkiaShader* copy() = 0;
|
|
void copyFrom(const SkiaShader& shader);
|
|
|
|
virtual void describe(ProgramDescription& description, const Extensions& extensions);
|
|
virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
|
|
GLuint* textureUnit);
|
|
|
|
inline SkShader *getSkShader() {
|
|
return mKey;
|
|
}
|
|
|
|
inline bool blend() const {
|
|
return mBlend;
|
|
}
|
|
|
|
Type type() const {
|
|
return mType;
|
|
}
|
|
|
|
virtual void set(TextureCache* textureCache, GradientCache* gradientCache) {
|
|
mTextureCache = textureCache;
|
|
mGradientCache = gradientCache;
|
|
}
|
|
|
|
virtual void updateTransforms(Program* program, const mat4& modelView,
|
|
const Snapshot& snapshot) {
|
|
}
|
|
|
|
uint32_t getGenerationId() {
|
|
return mGenerationId;
|
|
}
|
|
|
|
void setMatrix(SkMatrix* matrix) {
|
|
updateLocalMatrix(matrix);
|
|
mGenerationId++;
|
|
}
|
|
|
|
void updateLocalMatrix(const SkMatrix* matrix) {
|
|
if (matrix) {
|
|
mat4 localMatrix(*matrix);
|
|
mShaderMatrix.loadInverse(localMatrix);
|
|
} else {
|
|
mShaderMatrix.loadIdentity();
|
|
}
|
|
}
|
|
|
|
void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView);
|
|
|
|
protected:
|
|
SkiaShader() {
|
|
}
|
|
|
|
/**
|
|
* The appropriate texture unit must have been activated prior to invoking
|
|
* this method.
|
|
*/
|
|
inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT);
|
|
|
|
Type mType;
|
|
SkShader* mKey;
|
|
SkShader::TileMode mTileX;
|
|
SkShader::TileMode mTileY;
|
|
bool mBlend;
|
|
|
|
TextureCache* mTextureCache;
|
|
GradientCache* mGradientCache;
|
|
|
|
mat4 mUnitMatrix;
|
|
mat4 mShaderMatrix;
|
|
|
|
private:
|
|
uint32_t mGenerationId;
|
|
}; // 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);
|
|
SkiaShader* copy();
|
|
|
|
void describe(ProgramDescription& description, const Extensions& extensions);
|
|
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
|
|
GLuint* textureUnit);
|
|
void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
|
|
|
|
private:
|
|
SkiaBitmapShader() {
|
|
}
|
|
|
|
/**
|
|
* This method does not work for n == 0.
|
|
*/
|
|
inline bool isPowerOfTwo(unsigned int n) {
|
|
return !(n & (n - 1));
|
|
}
|
|
|
|
SkBitmap* mBitmap;
|
|
Texture* mTexture;
|
|
GLenum mWrapS;
|
|
GLenum mWrapT;
|
|
}; // 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();
|
|
SkiaShader* copy();
|
|
|
|
void describe(ProgramDescription& description, const Extensions& extensions);
|
|
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
|
|
GLuint* textureUnit);
|
|
void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
|
|
|
|
private:
|
|
SkiaLinearGradientShader() {
|
|
}
|
|
|
|
float* mBounds;
|
|
uint32_t* mColors;
|
|
float* mPositions;
|
|
int mCount;
|
|
}; // struct SkiaLinearGradientShader
|
|
|
|
/**
|
|
* A shader that draws a sweep gradient.
|
|
*/
|
|
struct SkiaSweepGradientShader: public SkiaShader {
|
|
SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count,
|
|
SkShader* key, SkMatrix* matrix, bool blend);
|
|
~SkiaSweepGradientShader();
|
|
SkiaShader* copy();
|
|
|
|
virtual void describe(ProgramDescription& description, const Extensions& extensions);
|
|
void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot,
|
|
GLuint* textureUnit);
|
|
void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot);
|
|
|
|
protected:
|
|
SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions,
|
|
int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
|
|
SkiaSweepGradientShader() {
|
|
}
|
|
|
|
uint32_t* mColors;
|
|
float* mPositions;
|
|
int mCount;
|
|
}; // struct SkiaSweepGradientShader
|
|
|
|
/**
|
|
* A shader that draws a circular gradient.
|
|
*/
|
|
struct SkiaCircularGradientShader: public SkiaSweepGradientShader {
|
|
SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions,
|
|
int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend);
|
|
SkiaShader* copy();
|
|
|
|
void describe(ProgramDescription& description, const Extensions& extensions);
|
|
|
|
private:
|
|
SkiaCircularGradientShader() {
|
|
}
|
|
}; // struct SkiaCircularGradientShader
|
|
|
|
/**
|
|
* 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();
|
|
SkiaShader* copy();
|
|
|
|
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:
|
|
SkiaComposeShader(): mCleanup(false) {
|
|
}
|
|
|
|
void cleanup() {
|
|
mCleanup = true;
|
|
}
|
|
|
|
SkiaShader* mFirst;
|
|
SkiaShader* mSecond;
|
|
SkXfermode::Mode mMode;
|
|
|
|
bool mCleanup;
|
|
}; // struct SkiaComposeShader
|
|
|
|
}; // namespace uirenderer
|
|
}; // namespace android
|
|
|
|
#endif // ANDROID_HWUI_SKIA_SHADER_H
|