Merge "Add rounded rects and circles support to OpenGLRenderer." into honeycomb
This commit is contained in:
@@ -635,9 +635,13 @@ class GLES20Canvas extends HardwareCanvas {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawCircle(float cx, float cy, float radius, Paint paint) {
|
public void drawCircle(float cx, float cy, float radius, Paint paint) {
|
||||||
throw new UnsupportedOperationException();
|
boolean hasModifier = setupModifiers(paint);
|
||||||
|
nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
|
||||||
|
if (hasModifier) nResetModifiers(mRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawColor(int color) {
|
public void drawColor(int color) {
|
||||||
drawColor(color, PorterDuff.Mode.SRC_OVER);
|
drawColor(color, PorterDuff.Mode.SRC_OVER);
|
||||||
@@ -773,9 +777,15 @@ class GLES20Canvas extends HardwareCanvas {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
|
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
|
||||||
// TODO: Implement
|
boolean hasModifier = setupModifiers(paint);
|
||||||
|
nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
|
||||||
|
rx, ry, paint.mNativePaint);
|
||||||
|
if (hasModifier) nResetModifiers(mRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private native void nDrawRoundRect(int renderer, float left, float top,
|
||||||
|
float right, float bottom, float rx, float y, int paint);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
|
public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
|
||||||
if ((index | count | (index + count) | (text.length - index - count)) < 0) {
|
if ((index | count | (index + count) | (text.length - index - count)) < 0) {
|
||||||
|
|||||||
@@ -299,6 +299,17 @@ static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas,
|
|||||||
renderer->drawRect(left, top, right, bottom, paint);
|
renderer->drawRect(left, top, right, bottom, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas,
|
||||||
|
OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
|
||||||
|
jfloat rx, jfloat ry, SkPaint* paint) {
|
||||||
|
renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas,
|
||||||
|
OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) {
|
||||||
|
renderer->drawCircle(x, y, radius, paint);
|
||||||
|
}
|
||||||
|
|
||||||
static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
|
static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
|
||||||
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
|
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
|
||||||
SkRegion::Iterator it(*region);
|
SkRegion::Iterator it(*region);
|
||||||
@@ -570,6 +581,8 @@ static JNINativeMethod gMethods[] = {
|
|||||||
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
|
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
|
||||||
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
|
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
|
||||||
{ "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects },
|
{ "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects },
|
||||||
|
{ "nDrawRoundRect", "(IFFFFFFI)V", (void*) android_view_GLES20Canvas_drawRoundRect },
|
||||||
|
{ "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle },
|
||||||
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
|
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
|
||||||
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
|
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ ifeq ($(USE_OPENGL_RENDERER),true)
|
|||||||
Program.cpp \
|
Program.cpp \
|
||||||
ProgramCache.cpp \
|
ProgramCache.cpp \
|
||||||
ResourceCache.cpp \
|
ResourceCache.cpp \
|
||||||
|
ShapeCache.cpp \
|
||||||
SkiaColorFilter.cpp \
|
SkiaColorFilter.cpp \
|
||||||
SkiaShader.cpp \
|
SkiaShader.cpp \
|
||||||
TextureCache.cpp \
|
TextureCache.cpp \
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ void Caches::dumpMemoryUsage() {
|
|||||||
LOGD(" LayerCache %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
|
LOGD(" LayerCache %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
|
||||||
LOGD(" GradientCache %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
|
LOGD(" GradientCache %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
|
||||||
LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
|
LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
|
||||||
|
LOGD(" CircleShapeCache %8d / %8d",
|
||||||
|
circleShapeCache.getSize(), circleShapeCache.getMaxSize());
|
||||||
|
LOGD(" RoundRectShapeCache %8d / %8d",
|
||||||
|
roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
|
||||||
LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(),
|
LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(),
|
||||||
dropShadowCache.getMaxSize());
|
dropShadowCache.getMaxSize());
|
||||||
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
|
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include "PatchCache.h"
|
#include "PatchCache.h"
|
||||||
#include "ProgramCache.h"
|
#include "ProgramCache.h"
|
||||||
#include "PathCache.h"
|
#include "PathCache.h"
|
||||||
|
#include "ShapeCache.h"
|
||||||
#include "TextDropShadowCache.h"
|
#include "TextDropShadowCache.h"
|
||||||
#include "FboCache.h"
|
#include "FboCache.h"
|
||||||
#include "ResourceCache.h"
|
#include "ResourceCache.h"
|
||||||
@@ -159,6 +160,8 @@ public:
|
|||||||
GradientCache gradientCache;
|
GradientCache gradientCache;
|
||||||
ProgramCache programCache;
|
ProgramCache programCache;
|
||||||
PathCache pathCache;
|
PathCache pathCache;
|
||||||
|
RoundRectShapeCache roundRectShapeCache;
|
||||||
|
CircleShapeCache circleShapeCache;
|
||||||
PatchCache patchCache;
|
PatchCache patchCache;
|
||||||
TextDropShadowCache dropShadowCache;
|
TextDropShadowCache dropShadowCache;
|
||||||
FboCache fboCache;
|
FboCache fboCache;
|
||||||
|
|||||||
@@ -45,6 +45,9 @@
|
|||||||
// Turn on to display debug info about paths
|
// Turn on to display debug info about paths
|
||||||
#define DEBUG_PATHS 0
|
#define DEBUG_PATHS 0
|
||||||
|
|
||||||
|
// Turn on to display debug info about shapes
|
||||||
|
#define DEBUG_SHAPES 0
|
||||||
|
|
||||||
// Turn on to display debug info about textures
|
// Turn on to display debug info about textures
|
||||||
#define DEBUG_TEXTURES 0
|
#define DEBUG_TEXTURES 0
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ const char* DisplayList::OP_NAMES[] = {
|
|||||||
"DrawPatch",
|
"DrawPatch",
|
||||||
"DrawColor",
|
"DrawColor",
|
||||||
"DrawRect",
|
"DrawRect",
|
||||||
|
"DrawRoundRect",
|
||||||
|
"DrawCircle",
|
||||||
"DrawPath",
|
"DrawPath",
|
||||||
"DrawLines",
|
"DrawLines",
|
||||||
"DrawText",
|
"DrawText",
|
||||||
@@ -332,6 +334,15 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) {
|
|||||||
renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case DrawRoundRect: {
|
||||||
|
renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
|
||||||
|
getFloat(), getFloat(), getPaint());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DrawCircle: {
|
||||||
|
renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
|
||||||
|
}
|
||||||
|
break;
|
||||||
case DrawPath: {
|
case DrawPath: {
|
||||||
renderer.drawPath(getPath(), getPaint());
|
renderer.drawPath(getPath(), getPaint());
|
||||||
}
|
}
|
||||||
@@ -601,6 +612,21 @@ void DisplayListRenderer::drawRect(float left, float top, float right, float bot
|
|||||||
addPaint(paint);
|
addPaint(paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
|
||||||
|
float rx, float ry, SkPaint* paint) {
|
||||||
|
addOp(DisplayList::DrawRoundRect);
|
||||||
|
addBounds(left, top, right, bottom);
|
||||||
|
addPoint(rx, ry);
|
||||||
|
addPaint(paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
|
||||||
|
addOp(DisplayList::DrawCircle);
|
||||||
|
addPoint(x, y);
|
||||||
|
addFloat(radius);
|
||||||
|
addPaint(paint);
|
||||||
|
}
|
||||||
|
|
||||||
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
||||||
addOp(DisplayList::DrawPath);
|
addOp(DisplayList::DrawPath);
|
||||||
addPath(path);
|
addPath(path);
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ public:
|
|||||||
DrawPatch,
|
DrawPatch,
|
||||||
DrawColor,
|
DrawColor,
|
||||||
DrawRect,
|
DrawRect,
|
||||||
|
DrawRoundRect,
|
||||||
|
DrawCircle,
|
||||||
DrawPath,
|
DrawPath,
|
||||||
DrawLines,
|
DrawLines,
|
||||||
DrawText,
|
DrawText,
|
||||||
@@ -270,6 +272,9 @@ public:
|
|||||||
float left, float top, float right, float bottom, SkPaint* paint);
|
float left, float top, float right, float bottom, SkPaint* paint);
|
||||||
void drawColor(int color, SkXfermode::Mode mode);
|
void drawColor(int color, SkXfermode::Mode mode);
|
||||||
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
|
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
|
||||||
|
void drawRoundRect(float left, float top, float right, float bottom,
|
||||||
|
float rx, float ry, SkPaint* paint);
|
||||||
|
void drawCircle(float x, float y, float radius, SkPaint* paint);
|
||||||
void drawPath(SkPath* path, SkPaint* paint);
|
void drawPath(SkPath* path, SkPaint* paint);
|
||||||
void drawLines(float* points, int count, SkPaint* paint);
|
void drawLines(float* points, int count, SkPaint* paint);
|
||||||
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
|
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
|
||||||
|
|||||||
@@ -1305,6 +1305,38 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
|
|||||||
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
|
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
|
||||||
|
float rx, float ry, SkPaint* paint) {
|
||||||
|
if (mSnapshot->isIgnored()) return;
|
||||||
|
|
||||||
|
glActiveTexture(gTextureUnits[0]);
|
||||||
|
|
||||||
|
const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
|
||||||
|
right - left, bottom - top, rx, ry, paint);
|
||||||
|
if (!texture) return;
|
||||||
|
const AutoTexture autoCleanup(texture);
|
||||||
|
|
||||||
|
const float x = left + texture->left - texture->offset;
|
||||||
|
const float y = top + texture->top - texture->offset;
|
||||||
|
|
||||||
|
drawPathTexture(texture, x, y, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
|
||||||
|
if (mSnapshot->isIgnored()) return;
|
||||||
|
|
||||||
|
glActiveTexture(gTextureUnits[0]);
|
||||||
|
|
||||||
|
const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
|
||||||
|
if (!texture) return;
|
||||||
|
const AutoTexture autoCleanup(texture);
|
||||||
|
|
||||||
|
const float left = (x - radius) + texture->left - texture->offset;
|
||||||
|
const float top = (y - radius) + texture->top - texture->offset;
|
||||||
|
|
||||||
|
drawPathTexture(texture, left, top, paint);
|
||||||
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
|
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
|
||||||
if (quickReject(left, top, right, bottom)) {
|
if (quickReject(left, top, right, bottom)) {
|
||||||
return;
|
return;
|
||||||
@@ -1453,8 +1485,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
|
|||||||
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
||||||
if (mSnapshot->isIgnored()) return;
|
if (mSnapshot->isIgnored()) return;
|
||||||
|
|
||||||
GLuint textureUnit = 0;
|
glActiveTexture(gTextureUnits[0]);
|
||||||
glActiveTexture(gTextureUnits[textureUnit]);
|
|
||||||
|
|
||||||
const PathTexture* texture = mCaches.pathCache.get(path, paint);
|
const PathTexture* texture = mCaches.pathCache.get(path, paint);
|
||||||
if (!texture) return;
|
if (!texture) return;
|
||||||
@@ -1463,31 +1494,7 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
|
|||||||
const float x = texture->left - texture->offset;
|
const float x = texture->left - texture->offset;
|
||||||
const float y = texture->top - texture->offset;
|
const float y = texture->top - texture->offset;
|
||||||
|
|
||||||
if (quickReject(x, y, x + texture->width, y + texture->height)) {
|
drawPathTexture(texture, x, y, paint);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int alpha;
|
|
||||||
SkXfermode::Mode mode;
|
|
||||||
getAlphaAndMode(paint, &alpha, &mode);
|
|
||||||
|
|
||||||
setupDraw();
|
|
||||||
setupDrawWithTexture(true);
|
|
||||||
setupDrawAlpha8Color(paint->getColor(), alpha);
|
|
||||||
setupDrawColorFilter();
|
|
||||||
setupDrawShader();
|
|
||||||
setupDrawBlending(true, mode);
|
|
||||||
setupDrawProgram();
|
|
||||||
setupDrawModelView(x, y, x + texture->width, y + texture->height);
|
|
||||||
setupDrawTexture(texture->id);
|
|
||||||
setupDrawPureColorUniforms();
|
|
||||||
setupDrawColorFilterUniforms();
|
|
||||||
setupDrawShaderUniforms();
|
|
||||||
setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
|
|
||||||
|
|
||||||
finishDrawTexture();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
|
void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
|
||||||
@@ -1583,6 +1590,35 @@ void OpenGLRenderer::setupShadow(float radius, float dx, float dy, int color) {
|
|||||||
// Drawing implementation
|
// Drawing implementation
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
|
||||||
|
float x, float y, SkPaint* paint) {
|
||||||
|
if (quickReject(x, y, x + texture->width, y + texture->height)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int alpha;
|
||||||
|
SkXfermode::Mode mode;
|
||||||
|
getAlphaAndMode(paint, &alpha, &mode);
|
||||||
|
|
||||||
|
setupDraw();
|
||||||
|
setupDrawWithTexture(true);
|
||||||
|
setupDrawAlpha8Color(paint->getColor(), alpha);
|
||||||
|
setupDrawColorFilter();
|
||||||
|
setupDrawShader();
|
||||||
|
setupDrawBlending(true, mode);
|
||||||
|
setupDrawProgram();
|
||||||
|
setupDrawModelView(x, y, x + texture->width, y + texture->height);
|
||||||
|
setupDrawTexture(texture->id);
|
||||||
|
setupDrawPureColorUniforms();
|
||||||
|
setupDrawColorFilterUniforms();
|
||||||
|
setupDrawShaderUniforms();
|
||||||
|
setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
|
||||||
|
|
||||||
|
finishDrawTexture();
|
||||||
|
}
|
||||||
|
|
||||||
// Same values used by Skia
|
// Same values used by Skia
|
||||||
#define kStdStrikeThru_Offset (-6.0f / 21.0f)
|
#define kStdStrikeThru_Offset (-6.0f / 21.0f)
|
||||||
#define kStdUnderline_Offset (1.0f / 9.0f)
|
#define kStdUnderline_Offset (1.0f / 9.0f)
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ public:
|
|||||||
float left, float top, float right, float bottom, SkPaint* paint);
|
float left, float top, float right, float bottom, SkPaint* paint);
|
||||||
virtual void drawColor(int color, SkXfermode::Mode mode);
|
virtual void drawColor(int color, SkXfermode::Mode mode);
|
||||||
virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
|
virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
|
||||||
|
virtual void drawRoundRect(float left, float top, float right, float bottom,
|
||||||
|
float rx, float ry, SkPaint* paint);
|
||||||
|
virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
|
||||||
virtual void drawPath(SkPath* path, SkPaint* paint);
|
virtual void drawPath(SkPath* path, SkPaint* paint);
|
||||||
virtual void drawLines(float* points, int count, SkPaint* paint);
|
virtual void drawLines(float* points, int count, SkPaint* paint);
|
||||||
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
|
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
|
||||||
@@ -343,6 +346,8 @@ private:
|
|||||||
void drawTextDecorations(const char* text, int bytesCount, float length,
|
void drawTextDecorations(const char* text, int bytesCount, float length,
|
||||||
float x, float y, SkPaint* paint);
|
float x, float y, SkPaint* paint);
|
||||||
|
|
||||||
|
void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the texture coordinates stored in mMeshVertices. Setting the values
|
* Resets the texture coordinates stored in mMeshVertices. Setting the values
|
||||||
* back to default is achieved by calling:
|
* back to default is achieved by calling:
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ enum DebugLevel {
|
|||||||
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
|
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
|
||||||
#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
|
#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
|
||||||
#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
|
#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
|
||||||
|
#define PROPERTY_SHAPE_CACHE_SIZE "ro.hwui.shape_cache_size"
|
||||||
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
|
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
|
||||||
#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
|
#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
|
||||||
|
|
||||||
@@ -66,6 +67,7 @@ enum DebugLevel {
|
|||||||
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
|
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
|
||||||
#define DEFAULT_LAYER_CACHE_SIZE 8.0f
|
#define DEFAULT_LAYER_CACHE_SIZE 8.0f
|
||||||
#define DEFAULT_PATH_CACHE_SIZE 4.0f
|
#define DEFAULT_PATH_CACHE_SIZE 4.0f
|
||||||
|
#define DEFAULT_SHAPE_CACHE_SIZE 1.0f
|
||||||
#define DEFAULT_PATCH_CACHE_SIZE 512
|
#define DEFAULT_PATCH_CACHE_SIZE 512
|
||||||
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
|
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
|
||||||
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
|
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
|
||||||
|
|||||||
62
libs/hwui/ShapeCache.cpp
Normal file
62
libs/hwui/ShapeCache.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOG_TAG "OpenGLRenderer"
|
||||||
|
|
||||||
|
#include "ShapeCache.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace uirenderer {
|
||||||
|
|
||||||
|
RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>() {
|
||||||
|
}
|
||||||
|
|
||||||
|
PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
|
||||||
|
float rx, float ry, SkPaint* paint) {
|
||||||
|
RoundRectShapeCacheEntry entry(width, height, rx, ry, paint);
|
||||||
|
PathTexture* texture = get(entry);
|
||||||
|
|
||||||
|
if (!texture) {
|
||||||
|
SkPath path;
|
||||||
|
SkRect r;
|
||||||
|
r.set(0.0f, 0.0f, width, height);
|
||||||
|
path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
|
||||||
|
|
||||||
|
texture = addTexture(entry, &path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>() {
|
||||||
|
}
|
||||||
|
|
||||||
|
PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
|
||||||
|
CircleShapeCacheEntry entry(radius, paint);
|
||||||
|
PathTexture* texture = get(entry);
|
||||||
|
|
||||||
|
if (!texture) {
|
||||||
|
SkPath path;
|
||||||
|
path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
|
||||||
|
|
||||||
|
texture = addTexture(entry, &path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace uirenderer
|
||||||
|
}; // namespace android
|
||||||
464
libs/hwui/ShapeCache.h
Normal file
464
libs/hwui/ShapeCache.h
Normal file
@@ -0,0 +1,464 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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_SHAPE_CACHE_H
|
||||||
|
#define ANDROID_HWUI_SHAPE_CACHE_H
|
||||||
|
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
|
||||||
|
#include <SkCanvas.h>
|
||||||
|
#include <SkRect.h>
|
||||||
|
|
||||||
|
#include "PathCache.h"
|
||||||
|
#include "Properties.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace uirenderer {
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Defines
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
#if DEBUG_SHAPES
|
||||||
|
#define SHAPE_LOGD(...) LOGD(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define SHAPE_LOGD(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Classes
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describe a shape in the shape cache.
|
||||||
|
*/
|
||||||
|
struct ShapeCacheEntry {
|
||||||
|
enum ShapeType {
|
||||||
|
kShapeNone,
|
||||||
|
kShapeRoundRect,
|
||||||
|
kShapeCircle,
|
||||||
|
kShapeOval,
|
||||||
|
kShapeArc
|
||||||
|
};
|
||||||
|
|
||||||
|
ShapeCacheEntry() {
|
||||||
|
shapeType = kShapeNone;
|
||||||
|
join = SkPaint::kDefault_Join;
|
||||||
|
cap = SkPaint::kDefault_Cap;
|
||||||
|
style = SkPaint::kFill_Style;
|
||||||
|
miter = 4.0f;
|
||||||
|
strokeWidth = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeCacheEntry(const ShapeCacheEntry& entry):
|
||||||
|
shapeType(entry.shapeType), join(entry.join), cap(entry.cap),
|
||||||
|
style(entry.style), miter(entry.miter),
|
||||||
|
strokeWidth(entry.strokeWidth) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ShapeCacheEntry(ShapeType type, SkPaint* paint) {
|
||||||
|
shapeType = type;
|
||||||
|
join = paint->getStrokeJoin();
|
||||||
|
cap = paint->getStrokeCap();
|
||||||
|
float v = paint->getStrokeMiter();
|
||||||
|
miter = *(uint32_t*) &v;
|
||||||
|
v = paint->getStrokeWidth();
|
||||||
|
strokeWidth = *(uint32_t*) &v;
|
||||||
|
style = paint->getStyle();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ShapeCacheEntry() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// shapeType must be checked in subclasses operator<
|
||||||
|
ShapeType shapeType;
|
||||||
|
SkPaint::Join join;
|
||||||
|
SkPaint::Cap cap;
|
||||||
|
SkPaint::Style style;
|
||||||
|
uint32_t miter;
|
||||||
|
uint32_t strokeWidth;
|
||||||
|
|
||||||
|
bool operator<(const ShapeCacheEntry& rhs) const {
|
||||||
|
LTE_INT(shapeType) {
|
||||||
|
LTE_INT(join) {
|
||||||
|
LTE_INT(cap) {
|
||||||
|
LTE_INT(style) {
|
||||||
|
LTE_INT(miter) {
|
||||||
|
LTE_INT(strokeWidth) {
|
||||||
|
return lessThan(rhs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool lessThan(const ShapeCacheEntry& rhs) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}; // struct ShapeCacheEntry
|
||||||
|
|
||||||
|
|
||||||
|
struct RoundRectShapeCacheEntry: public ShapeCacheEntry {
|
||||||
|
RoundRectShapeCacheEntry(float width, float height, float rx, float ry, SkPaint* paint):
|
||||||
|
ShapeCacheEntry(ShapeCacheEntry::kShapeRoundRect, paint) {
|
||||||
|
mWidth = *(uint32_t*) &width;
|
||||||
|
mHeight = *(uint32_t*) &height;
|
||||||
|
mRx = *(uint32_t*) ℞
|
||||||
|
mRy = *(uint32_t*) &ry;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoundRectShapeCacheEntry(): ShapeCacheEntry() {
|
||||||
|
mWidth = 0;
|
||||||
|
mHeight = 0;
|
||||||
|
mRx = 0;
|
||||||
|
mRy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RoundRectShapeCacheEntry(const RoundRectShapeCacheEntry& entry):
|
||||||
|
ShapeCacheEntry(entry) {
|
||||||
|
mWidth = entry.mWidth;
|
||||||
|
mHeight = entry.mHeight;
|
||||||
|
mRx = entry.mRx;
|
||||||
|
mRy = entry.mRy;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lessThan(const ShapeCacheEntry& r) const {
|
||||||
|
const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r;
|
||||||
|
LTE_INT(mWidth) {
|
||||||
|
LTE_INT(mHeight) {
|
||||||
|
LTE_INT(mRx) {
|
||||||
|
LTE_INT(mRy) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t mWidth;
|
||||||
|
uint32_t mHeight;
|
||||||
|
uint32_t mRx;
|
||||||
|
uint32_t mRy;
|
||||||
|
}; // RoundRectShapeCacheEntry
|
||||||
|
|
||||||
|
struct CircleShapeCacheEntry: public ShapeCacheEntry {
|
||||||
|
CircleShapeCacheEntry(float radius, SkPaint* paint):
|
||||||
|
ShapeCacheEntry(ShapeCacheEntry::kShapeCircle, paint) {
|
||||||
|
mRadius = *(uint32_t*) &radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleShapeCacheEntry(): ShapeCacheEntry() {
|
||||||
|
mRadius = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleShapeCacheEntry(const CircleShapeCacheEntry& entry):
|
||||||
|
ShapeCacheEntry(entry) {
|
||||||
|
mRadius = entry.mRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool lessThan(const ShapeCacheEntry& r) const {
|
||||||
|
const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r;
|
||||||
|
LTE_INT(mRadius) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t mRadius;
|
||||||
|
}; // CircleShapeCacheEntry
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple LRU shape cache. The cache has a maximum size expressed in bytes.
|
||||||
|
* Any texture added to the cache causing the cache to grow beyond the maximum
|
||||||
|
* allowed size will also cause the oldest texture to be kicked out.
|
||||||
|
*/
|
||||||
|
template<typename Entry>
|
||||||
|
class ShapeCache: public OnEntryRemoved<Entry, PathTexture*> {
|
||||||
|
public:
|
||||||
|
ShapeCache();
|
||||||
|
ShapeCache(uint32_t maxByteSize);
|
||||||
|
~ShapeCache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used as a callback when an entry is removed from the cache.
|
||||||
|
* Do not invoke directly.
|
||||||
|
*/
|
||||||
|
void operator()(Entry& path, PathTexture*& texture);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the cache. This causes all textures to be deleted.
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum size of the cache in bytes.
|
||||||
|
*/
|
||||||
|
void setMaxSize(uint32_t maxSize);
|
||||||
|
/**
|
||||||
|
* Returns the maximum size of the cache in bytes.
|
||||||
|
*/
|
||||||
|
uint32_t getMaxSize();
|
||||||
|
/**
|
||||||
|
* Returns the current size of the cache in bytes.
|
||||||
|
*/
|
||||||
|
uint32_t getSize();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint);
|
||||||
|
|
||||||
|
PathTexture* get(Entry entry) {
|
||||||
|
return mCache.get(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Generates the texture from a bitmap into the specified texture structure.
|
||||||
|
*/
|
||||||
|
void generateTexture(SkBitmap& bitmap, Texture* texture);
|
||||||
|
|
||||||
|
void removeTexture(PathTexture* texture);
|
||||||
|
|
||||||
|
void init();
|
||||||
|
|
||||||
|
GenerationCache<Entry, PathTexture*> mCache;
|
||||||
|
uint32_t mSize;
|
||||||
|
uint32_t mMaxSize;
|
||||||
|
GLuint mMaxTextureSize;
|
||||||
|
|
||||||
|
bool mDebugEnabled;
|
||||||
|
}; // class ShapeCache
|
||||||
|
|
||||||
|
class RoundRectShapeCache: public ShapeCache<RoundRectShapeCacheEntry> {
|
||||||
|
public:
|
||||||
|
RoundRectShapeCache();
|
||||||
|
|
||||||
|
PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
|
||||||
|
}; // class RoundRectShapeCache
|
||||||
|
|
||||||
|
class CircleShapeCache: public ShapeCache<CircleShapeCacheEntry> {
|
||||||
|
public:
|
||||||
|
CircleShapeCache();
|
||||||
|
|
||||||
|
PathTexture* getCircle(float radius, SkPaint* paint);
|
||||||
|
}; // class RoundRectShapeCache
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructors/destructor
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
ShapeCache<Entry>::ShapeCache():
|
||||||
|
mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
|
||||||
|
mSize(0), mMaxSize(MB(DEFAULT_SHAPE_CACHE_SIZE)) {
|
||||||
|
char property[PROPERTY_VALUE_MAX];
|
||||||
|
if (property_get(PROPERTY_SHAPE_CACHE_SIZE, property, NULL) > 0) {
|
||||||
|
LOGD(" Setting shape cache size to %sMB", property);
|
||||||
|
setMaxSize(MB(atof(property)));
|
||||||
|
} else {
|
||||||
|
LOGD(" Using default shape cache size of %.2fMB", DEFAULT_SHAPE_CACHE_SIZE);
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
ShapeCache<Entry>::ShapeCache(uint32_t maxByteSize):
|
||||||
|
mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
|
||||||
|
mSize(0), mMaxSize(maxByteSize) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
ShapeCache<Entry>::~ShapeCache() {
|
||||||
|
mCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
void ShapeCache<Entry>::init() {
|
||||||
|
mCache.setOnEntryRemovedListener(this);
|
||||||
|
|
||||||
|
GLint maxTextureSize;
|
||||||
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||||
|
mMaxTextureSize = maxTextureSize;
|
||||||
|
|
||||||
|
mDebugEnabled = readDebugLevel() & kDebugCaches;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Size management
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
uint32_t ShapeCache<Entry>::getSize() {
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
uint32_t ShapeCache<Entry>::getMaxSize() {
|
||||||
|
return mMaxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
void ShapeCache<Entry>::setMaxSize(uint32_t maxSize) {
|
||||||
|
mMaxSize = maxSize;
|
||||||
|
while (mSize > mMaxSize) {
|
||||||
|
mCache.removeOldest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Callbacks
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
void ShapeCache<Entry>::operator()(Entry& path, PathTexture*& texture) {
|
||||||
|
removeTexture(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Caching
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
void ShapeCache<Entry>::removeTexture(PathTexture* texture) {
|
||||||
|
if (texture) {
|
||||||
|
const uint32_t size = texture->width * texture->height;
|
||||||
|
mSize -= size;
|
||||||
|
|
||||||
|
SHAPE_LOGD("ShapeCache::callback: delete path: name, size, mSize = %d, %d, %d",
|
||||||
|
texture->id, size, mSize);
|
||||||
|
if (mDebugEnabled) {
|
||||||
|
LOGD("Path deleted, size = %d", size);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteTextures(1, &texture->id);
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path,
|
||||||
|
const SkPaint* paint) {
|
||||||
|
const SkRect& bounds = path->getBounds();
|
||||||
|
|
||||||
|
const float pathWidth = fmax(bounds.width(), 1.0f);
|
||||||
|
const float pathHeight = fmax(bounds.height(), 1.0f);
|
||||||
|
|
||||||
|
if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
|
||||||
|
LOGW("Shape too large to be rendered into a texture");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float offset = paint->getStrokeWidth() * 1.5f;
|
||||||
|
const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
|
||||||
|
const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
|
||||||
|
|
||||||
|
const uint32_t size = width * height;
|
||||||
|
// Don't even try to cache a bitmap that's bigger than the cache
|
||||||
|
if (size < mMaxSize) {
|
||||||
|
while (mSize + size > mMaxSize) {
|
||||||
|
mCache.removeOldest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PathTexture* texture = new PathTexture;
|
||||||
|
texture->left = bounds.fLeft;
|
||||||
|
texture->top = bounds.fTop;
|
||||||
|
texture->offset = offset;
|
||||||
|
texture->width = width;
|
||||||
|
texture->height = height;
|
||||||
|
texture->generation = path->getGenerationID();
|
||||||
|
|
||||||
|
SkBitmap bitmap;
|
||||||
|
bitmap.setConfig(SkBitmap::kA8_Config, width, height);
|
||||||
|
bitmap.allocPixels();
|
||||||
|
bitmap.eraseColor(0);
|
||||||
|
|
||||||
|
SkPaint pathPaint(*paint);
|
||||||
|
|
||||||
|
// Make sure the paint is opaque, color, alpha, filter, etc.
|
||||||
|
// will be applied later when compositing the alpha8 texture
|
||||||
|
pathPaint.setColor(0xff000000);
|
||||||
|
pathPaint.setAlpha(255);
|
||||||
|
pathPaint.setColorFilter(NULL);
|
||||||
|
pathPaint.setMaskFilter(NULL);
|
||||||
|
pathPaint.setShader(NULL);
|
||||||
|
SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
|
||||||
|
pathPaint.setXfermode(mode)->safeUnref();
|
||||||
|
|
||||||
|
SkCanvas canvas(bitmap);
|
||||||
|
canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset);
|
||||||
|
canvas.drawPath(*path, pathPaint);
|
||||||
|
|
||||||
|
generateTexture(bitmap, texture);
|
||||||
|
|
||||||
|
if (size < mMaxSize) {
|
||||||
|
mSize += size;
|
||||||
|
SHAPE_LOGD("ShapeCache::get: create path: name, size, mSize = %d, %d, %d",
|
||||||
|
texture->id, size, mSize);
|
||||||
|
if (mDebugEnabled) {
|
||||||
|
LOGD("Shape created, size = %d", size);
|
||||||
|
}
|
||||||
|
mCache.put(entry, texture);
|
||||||
|
} else {
|
||||||
|
texture->cleanup = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
void ShapeCache<Entry>::clear() {
|
||||||
|
mCache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Entry>
|
||||||
|
void ShapeCache<Entry>::generateTexture(SkBitmap& bitmap, Texture* texture) {
|
||||||
|
SkAutoLockPixels alp(bitmap);
|
||||||
|
if (!bitmap.readyToDraw()) {
|
||||||
|
LOGE("Cannot generate texture from bitmap");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures(1, &texture->id);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||||
|
// Textures are Alpha8
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
texture->blend = true;
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
|
||||||
|
GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // namespace uirenderer
|
||||||
|
}; // namespace android
|
||||||
|
|
||||||
|
#endif // ANDROID_HWUI_SHAPE_CACHE_H
|
||||||
@@ -24,6 +24,15 @@
|
|||||||
android:label="HwUi"
|
android:label="HwUi"
|
||||||
android:hardwareAccelerated="true">
|
android:hardwareAccelerated="true">
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name="ShapesActivity"
|
||||||
|
android:label="_Shapes">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="SimplePatchActivity"
|
android:name="SimplePatchActivity"
|
||||||
android:label="_SimplePatch"
|
android:label="_SimplePatch"
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.test.hwui;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Paint;
|
||||||
|
import android.graphics.RectF;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
@SuppressWarnings({"UnusedDeclaration"})
|
||||||
|
public class ShapesActivity extends Activity {
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(new ShapesView(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ShapesView extends View {
|
||||||
|
private Paint mNormalPaint;
|
||||||
|
private Paint mStrokePaint;
|
||||||
|
private Paint mFillPaint;
|
||||||
|
private RectF mRect;
|
||||||
|
|
||||||
|
ShapesView(Context c) {
|
||||||
|
super(c);
|
||||||
|
|
||||||
|
mRect = new RectF(0.0f, 0.0f, 160.0f, 90.0f);
|
||||||
|
|
||||||
|
mNormalPaint = new Paint();
|
||||||
|
mNormalPaint.setAntiAlias(true);
|
||||||
|
mNormalPaint.setColor(0xff0000ff);
|
||||||
|
mNormalPaint.setStrokeWidth(6.0f);
|
||||||
|
mNormalPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
|
|
||||||
|
mStrokePaint = new Paint();
|
||||||
|
mStrokePaint.setAntiAlias(true);
|
||||||
|
mStrokePaint.setColor(0xff0000ff);
|
||||||
|
mStrokePaint.setStrokeWidth(6.0f);
|
||||||
|
mStrokePaint.setStyle(Paint.Style.STROKE);
|
||||||
|
|
||||||
|
mFillPaint = new Paint();
|
||||||
|
mFillPaint.setAntiAlias(true);
|
||||||
|
mFillPaint.setColor(0xff0000ff);
|
||||||
|
mFillPaint.setStyle(Paint.Style.FILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDraw(Canvas canvas) {
|
||||||
|
super.onDraw(canvas);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(50.0f, 50.0f);
|
||||||
|
canvas.drawRoundRect(mRect, 6.0f, 6.0f, mNormalPaint);
|
||||||
|
|
||||||
|
canvas.translate(0.0f, 110.0f);
|
||||||
|
canvas.drawRoundRect(mRect, 6.0f, 6.0f, mStrokePaint);
|
||||||
|
|
||||||
|
canvas.translate(0.0f, 110.0f);
|
||||||
|
canvas.drawRoundRect(mRect, 6.0f, 6.0f, mFillPaint);
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(250.0f, 50.0f);
|
||||||
|
canvas.drawCircle(80.0f, 45.0f, 45.0f, mNormalPaint);
|
||||||
|
|
||||||
|
canvas.translate(0.0f, 110.0f);
|
||||||
|
canvas.drawCircle(80.0f, 45.0f, 45.0f, mStrokePaint);
|
||||||
|
|
||||||
|
canvas.translate(0.0f, 110.0f);
|
||||||
|
canvas.drawCircle(80.0f, 45.0f, 45.0f, mFillPaint);
|
||||||
|
canvas.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user