101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/* 201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Copyright (C) 2011 The Android Open Source Project 301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * 401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * you may not use this file except in compliance with the License. 601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * You may obtain a copy of the License at 701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * 801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * 1001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Unless required by applicable law or agreed to in writing, software 1101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 1201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * See the License for the specific language governing permissions and 1401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * limitations under the License. 1501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 1601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 1701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#ifndef ANDROID_HWUI_SHAPE_CACHE_H 1801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#define ANDROID_HWUI_SHAPE_CACHE_H 1901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 2001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#include <GLES2/gl2.h> 2101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 22ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include <SkBitmap.h> 2301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#include <SkCanvas.h> 24ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include <SkPaint.h> 25ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include <SkPath.h> 2601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#include <SkRect.h> 2701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 28ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include "Debug.h" 2901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#include "Properties.h" 30ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include "Texture.h" 31ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include "utils/Compare.h" 32ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy#include "utils/GenerationCache.h" 3301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 3401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guynamespace android { 3501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guynamespace uirenderer { 3601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 3701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 3801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Defines 3901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 4001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 4101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Debug 4201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#if DEBUG_SHAPES 435baa3a62a97544669fba6d65a11c07f252e654ddSteve Block #define SHAPE_LOGD(...) ALOGD(__VA_ARGS__) 4401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#else 4501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy #define SHAPE_LOGD(...) 4601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#endif 4701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 4801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 4901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Classes 5001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 5101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 5201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/** 53ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy * Alpha texture used to represent a path. 54ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy */ 55ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guystruct PathTexture: public Texture { 56ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy PathTexture(): Texture() { 57ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy } 58ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy 59ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy /** 60ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy * Left coordinate of the path bounds. 61ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy */ 62ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy float left; 63ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy /** 64ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy * Top coordinate of the path bounds. 65ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy */ 66ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy float top; 67ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy /** 68ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy * Offset to draw the path at the correct origin. 69ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy */ 70ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy float offset; 71ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy}; // struct PathTexture 72ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy 73ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy/** 7401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Describe a shape in the shape cache. 7501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 7601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guystruct ShapeCacheEntry { 7701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy enum ShapeType { 7801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy kShapeNone, 79c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy kShapeRect, 8001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy kShapeRoundRect, 8101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy kShapeCircle, 8201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy kShapeOval, 83ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy kShapeArc, 84ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy kShapePath 8501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy }; 8601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 8701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy ShapeCacheEntry() { 8801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy shapeType = kShapeNone; 8901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy join = SkPaint::kDefault_Join; 9001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy cap = SkPaint::kDefault_Cap; 9101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy style = SkPaint::kFill_Style; 921af23a32d879db330eb5a08b21090ec60b604a32Romain Guy float v = 4.0f; 931af23a32d879db330eb5a08b21090ec60b604a32Romain Guy miter = *(uint32_t*) &v; 941af23a32d879db330eb5a08b21090ec60b604a32Romain Guy v = 1.0f; 951af23a32d879db330eb5a08b21090ec60b604a32Romain Guy strokeWidth = *(uint32_t*) &v; 961af23a32d879db330eb5a08b21090ec60b604a32Romain Guy pathEffect = NULL; 9701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 9801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 9901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy ShapeCacheEntry(ShapeType type, SkPaint* paint) { 10001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy shapeType = type; 10101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy join = paint->getStrokeJoin(); 10201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy cap = paint->getStrokeCap(); 10301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy float v = paint->getStrokeMiter(); 10401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy miter = *(uint32_t*) &v; 10501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy v = paint->getStrokeWidth(); 10601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy strokeWidth = *(uint32_t*) &v; 10701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy style = paint->getStyle(); 108b29cfbf768eab959b31410aafc0a99e20249e9d7Romain Guy pathEffect = paint->getPathEffect(); 10901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 11001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 11101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy virtual ~ShapeCacheEntry() { 11201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 11301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 11401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy ShapeType shapeType; 11501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy SkPaint::Join join; 11601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy SkPaint::Cap cap; 11701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy SkPaint::Style style; 11801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t miter; 11901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t strokeWidth; 120b29cfbf768eab959b31410aafc0a99e20249e9d7Romain Guy SkPathEffect* pathEffect; 12101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 12201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bool operator<(const ShapeCacheEntry& rhs) const { 12301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(shapeType) { 12401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(join) { 12501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(cap) { 12601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(style) { 12701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(miter) { 12801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(strokeWidth) { 129b29cfbf768eab959b31410aafc0a99e20249e9d7Romain Guy LTE_INT(pathEffect) { 130b29cfbf768eab959b31410aafc0a99e20249e9d7Romain Guy return lessThan(rhs); 131b29cfbf768eab959b31410aafc0a99e20249e9d7Romain Guy } 13201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 13301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 13401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 13501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 13601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 13701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 13801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return false; 13901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 14001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 14101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyprotected: 14201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy virtual bool lessThan(const ShapeCacheEntry& rhs) const { 14301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return false; 14401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 14501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // struct ShapeCacheEntry 14601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 14701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 14801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guystruct RoundRectShapeCacheEntry: public ShapeCacheEntry { 14901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy RoundRectShapeCacheEntry(float width, float height, float rx, float ry, SkPaint* paint): 15001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy ShapeCacheEntry(ShapeCacheEntry::kShapeRoundRect, paint) { 15101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mWidth = *(uint32_t*) &width; 15201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mHeight = *(uint32_t*) &height; 15301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mRx = *(uint32_t*) ℞ 15401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mRy = *(uint32_t*) &ry; 15501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 15601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 15701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy RoundRectShapeCacheEntry(): ShapeCacheEntry() { 15801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mWidth = 0; 15901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mHeight = 0; 16001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mRx = 0; 16101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mRy = 0; 16201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 16301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 16401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bool lessThan(const ShapeCacheEntry& r) const { 16501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r; 16601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(mWidth) { 16701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(mHeight) { 16801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(mRx) { 16901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(mRy) { 17001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return false; 17101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 17201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 17301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 17401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 17501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return false; 17601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 17701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 17801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyprivate: 17901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mWidth; 18001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mHeight; 18101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mRx; 18201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mRy; 18301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // RoundRectShapeCacheEntry 18401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 18501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guystruct CircleShapeCacheEntry: public ShapeCacheEntry { 18601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy CircleShapeCacheEntry(float radius, SkPaint* paint): 18701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy ShapeCacheEntry(ShapeCacheEntry::kShapeCircle, paint) { 18801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mRadius = *(uint32_t*) &radius; 18901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 19001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 19101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy CircleShapeCacheEntry(): ShapeCacheEntry() { 19201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mRadius = 0; 19301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 19401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 19501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bool lessThan(const ShapeCacheEntry& r) const { 19601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r; 19701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy LTE_INT(mRadius) { 19801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return false; 19901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 20001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return false; 20101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 20201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 20301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyprivate: 20401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mRadius; 20501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // CircleShapeCacheEntry 20601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 207c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guystruct OvalShapeCacheEntry: public ShapeCacheEntry { 208c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy OvalShapeCacheEntry(float width, float height, SkPaint* paint): 209c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy ShapeCacheEntry(ShapeCacheEntry::kShapeOval, paint) { 210c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy mWidth = *(uint32_t*) &width; 211c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy mHeight = *(uint32_t*) &height; 212c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 213c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 214c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy OvalShapeCacheEntry(): ShapeCacheEntry() { 215c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy mWidth = mHeight = 0; 216c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 217c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 218c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy bool lessThan(const ShapeCacheEntry& r) const { 219c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy const OvalShapeCacheEntry& rhs = (const OvalShapeCacheEntry&) r; 220c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy LTE_INT(mWidth) { 221c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy LTE_INT(mHeight) { 222c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy return false; 223c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 224c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 225c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy return false; 226c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 227c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 228c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guyprivate: 229c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy uint32_t mWidth; 230c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy uint32_t mHeight; 231c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}; // OvalShapeCacheEntry 232c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 233c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guystruct RectShapeCacheEntry: public ShapeCacheEntry { 234c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy RectShapeCacheEntry(float width, float height, SkPaint* paint): 235c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy ShapeCacheEntry(ShapeCacheEntry::kShapeRect, paint) { 236c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy mWidth = *(uint32_t*) &width; 237c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy mHeight = *(uint32_t*) &height; 238c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 239c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 240c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy RectShapeCacheEntry(): ShapeCacheEntry() { 241c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy mWidth = mHeight = 0; 242c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 243c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 244c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy bool lessThan(const ShapeCacheEntry& r) const { 245c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy const RectShapeCacheEntry& rhs = (const RectShapeCacheEntry&) r; 246c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy LTE_INT(mWidth) { 247c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy LTE_INT(mHeight) { 248c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy return false; 249c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 250c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 251c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy return false; 252c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy } 253c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 254c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guyprivate: 255c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy uint32_t mWidth; 256c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy uint32_t mHeight; 257c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}; // RectShapeCacheEntry 258c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 2598b2f5267f16c295f12faab810527cd6311997e34Romain Guystruct ArcShapeCacheEntry: public ShapeCacheEntry { 2608b2f5267f16c295f12faab810527cd6311997e34Romain Guy ArcShapeCacheEntry(float width, float height, float startAngle, float sweepAngle, 2618b2f5267f16c295f12faab810527cd6311997e34Romain Guy bool useCenter, SkPaint* paint): 2628b2f5267f16c295f12faab810527cd6311997e34Romain Guy ShapeCacheEntry(ShapeCacheEntry::kShapeArc, paint) { 2638b2f5267f16c295f12faab810527cd6311997e34Romain Guy mWidth = *(uint32_t*) &width; 2648b2f5267f16c295f12faab810527cd6311997e34Romain Guy mHeight = *(uint32_t*) &height; 2658b2f5267f16c295f12faab810527cd6311997e34Romain Guy mStartAngle = *(uint32_t*) &startAngle; 2668b2f5267f16c295f12faab810527cd6311997e34Romain Guy mSweepAngle = *(uint32_t*) &sweepAngle; 2678b2f5267f16c295f12faab810527cd6311997e34Romain Guy mUseCenter = useCenter ? 1 : 0; 2688b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2698b2f5267f16c295f12faab810527cd6311997e34Romain Guy 2708b2f5267f16c295f12faab810527cd6311997e34Romain Guy ArcShapeCacheEntry(): ShapeCacheEntry() { 2718b2f5267f16c295f12faab810527cd6311997e34Romain Guy mWidth = 0; 2728b2f5267f16c295f12faab810527cd6311997e34Romain Guy mHeight = 0; 2738b2f5267f16c295f12faab810527cd6311997e34Romain Guy mStartAngle = 0; 2748b2f5267f16c295f12faab810527cd6311997e34Romain Guy mSweepAngle = 0; 2758b2f5267f16c295f12faab810527cd6311997e34Romain Guy mUseCenter = 0; 2768b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2778b2f5267f16c295f12faab810527cd6311997e34Romain Guy 2788b2f5267f16c295f12faab810527cd6311997e34Romain Guy bool lessThan(const ShapeCacheEntry& r) const { 2798b2f5267f16c295f12faab810527cd6311997e34Romain Guy const ArcShapeCacheEntry& rhs = (const ArcShapeCacheEntry&) r; 2808b2f5267f16c295f12faab810527cd6311997e34Romain Guy LTE_INT(mWidth) { 2818b2f5267f16c295f12faab810527cd6311997e34Romain Guy LTE_INT(mHeight) { 2828b2f5267f16c295f12faab810527cd6311997e34Romain Guy LTE_INT(mStartAngle) { 2838b2f5267f16c295f12faab810527cd6311997e34Romain Guy LTE_INT(mSweepAngle) { 2848b2f5267f16c295f12faab810527cd6311997e34Romain Guy LTE_INT(mUseCenter) { 2858b2f5267f16c295f12faab810527cd6311997e34Romain Guy return false; 2868b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2878b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2888b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2898b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2908b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2918b2f5267f16c295f12faab810527cd6311997e34Romain Guy return false; 2928b2f5267f16c295f12faab810527cd6311997e34Romain Guy } 2938b2f5267f16c295f12faab810527cd6311997e34Romain Guy 2948b2f5267f16c295f12faab810527cd6311997e34Romain Guyprivate: 2958b2f5267f16c295f12faab810527cd6311997e34Romain Guy uint32_t mWidth; 2968b2f5267f16c295f12faab810527cd6311997e34Romain Guy uint32_t mHeight; 2978b2f5267f16c295f12faab810527cd6311997e34Romain Guy uint32_t mStartAngle; 2988b2f5267f16c295f12faab810527cd6311997e34Romain Guy uint32_t mSweepAngle; 2998b2f5267f16c295f12faab810527cd6311997e34Romain Guy uint32_t mUseCenter; 3008b2f5267f16c295f12faab810527cd6311997e34Romain Guy}; // ArcShapeCacheEntry 3018b2f5267f16c295f12faab810527cd6311997e34Romain Guy 30201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/** 30301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * A simple LRU shape cache. The cache has a maximum size expressed in bytes. 30401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Any texture added to the cache causing the cache to grow beyond the maximum 30501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * allowed size will also cause the oldest texture to be kicked out. 30601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 30701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<typename Entry> 30801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyclass ShapeCache: public OnEntryRemoved<Entry, PathTexture*> { 30901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guypublic: 310ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy ShapeCache(const char* name, const char* propertyName, float defaultSize); 31101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy ~ShapeCache(); 31201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 31301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy /** 31401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Used as a callback when an entry is removed from the cache. 31501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Do not invoke directly. 31601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 31701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy void operator()(Entry& path, PathTexture*& texture); 31801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 31901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy /** 32001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Clears the cache. This causes all textures to be deleted. 32101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 32201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy void clear(); 32301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 32401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy /** 32501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Sets the maximum size of the cache in bytes. 32601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 32701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy void setMaxSize(uint32_t maxSize); 32801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy /** 32901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Returns the maximum size of the cache in bytes. 33001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 33101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t getMaxSize(); 33201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy /** 33301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy * Returns the current size of the cache in bytes. 33401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy */ 33501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t getSize(); 33601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 33701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyprotected: 33801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint); 339fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy PathTexture* addTexture(const Entry& entry, SkBitmap* bitmap); 340fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy void addTexture(const Entry& entry, SkBitmap* bitmap, PathTexture* texture); 341fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 342fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy /** 343fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy * Ensures there is enough space in the cache for a texture of the specified 344fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy * dimensions. 345fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy */ 346fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy void purgeCache(uint32_t width, uint32_t height); 347fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 348fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height); 349fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy void initPaint(SkPaint& paint); 350fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 351fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy bool checkTextureSize(uint32_t width, uint32_t height); 35201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 35301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy PathTexture* get(Entry entry) { 35401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return mCache.get(entry); 35501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 35601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 35701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy void removeTexture(PathTexture* texture); 35801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 35901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy GenerationCache<Entry, PathTexture*> mCache; 36001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mSize; 36101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy uint32_t mMaxSize; 36201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy GLuint mMaxTextureSize; 36301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 364ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy char* mName; 36501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bool mDebugEnabled; 366ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy 367ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guyprivate: 368ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy /** 369ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy * Generates the texture from a bitmap into the specified texture structure. 370ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy */ 371ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy void generateTexture(SkBitmap& bitmap, Texture* texture); 372ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy 373ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy void init(); 37401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // class ShapeCache 37501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 37601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyclass RoundRectShapeCache: public ShapeCache<RoundRectShapeCacheEntry> { 37701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guypublic: 37801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy RoundRectShapeCache(); 37901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 38001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint); 38101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // class RoundRectShapeCache 38201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 38301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyclass CircleShapeCache: public ShapeCache<CircleShapeCacheEntry> { 38401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guypublic: 38501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy CircleShapeCache(); 38601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 38701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy PathTexture* getCircle(float radius, SkPaint* paint); 388c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}; // class CircleShapeCache 389c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 390c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guyclass OvalShapeCache: public ShapeCache<OvalShapeCacheEntry> { 391c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guypublic: 392c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy OvalShapeCache(); 393c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 394c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy PathTexture* getOval(float width, float height, SkPaint* paint); 395c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}; // class OvalShapeCache 396c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy 397c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guyclass RectShapeCache: public ShapeCache<RectShapeCacheEntry> { 398c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guypublic: 399c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy RectShapeCache(); 40001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 401c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy PathTexture* getRect(float width, float height, SkPaint* paint); 402c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}; // class RectShapeCache 40301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 4048b2f5267f16c295f12faab810527cd6311997e34Romain Guyclass ArcShapeCache: public ShapeCache<ArcShapeCacheEntry> { 4058b2f5267f16c295f12faab810527cd6311997e34Romain Guypublic: 4068b2f5267f16c295f12faab810527cd6311997e34Romain Guy ArcShapeCache(); 4078b2f5267f16c295f12faab810527cd6311997e34Romain Guy 4088b2f5267f16c295f12faab810527cd6311997e34Romain Guy PathTexture* getArc(float width, float height, float startAngle, float sweepAngle, 4098b2f5267f16c295f12faab810527cd6311997e34Romain Guy bool useCenter, SkPaint* paint); 4108b2f5267f16c295f12faab810527cd6311997e34Romain Guy}; // class ArcShapeCache 4118b2f5267f16c295f12faab810527cd6311997e34Romain Guy 41201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 41301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Constructors/destructor 41401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 41501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 41601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 417ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain GuyShapeCache<Entry>::ShapeCache(const char* name, const char* propertyName, float defaultSize): 41801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity), 419ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy mSize(0), mMaxSize(MB(defaultSize)) { 42001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy char property[PROPERTY_VALUE_MAX]; 421ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy if (property_get(propertyName, property, NULL) > 0) { 422c9855a53edfac818dc68714557185977556f849dRomain Guy INIT_LOGD(" Setting %s cache size to %sMB", name, property); 42301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy setMaxSize(MB(atof(property))); 42401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } else { 425c9855a53edfac818dc68714557185977556f849dRomain Guy INIT_LOGD(" Using default %s cache size of %.2fMB", name, defaultSize); 42601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 42701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 428ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy size_t len = strlen(name); 429ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy mName = new char[len + 1]; 430ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy strcpy(mName, name); 431ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy mName[len] = '\0'; 432ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy 43301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy init(); 43401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 43501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 43601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 43701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain GuyShapeCache<Entry>::~ShapeCache() { 43801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache.clear(); 439ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy delete[] mName; 44001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 44101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 44201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 44301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyvoid ShapeCache<Entry>::init() { 44401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache.setOnEntryRemovedListener(this); 44501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 44601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy GLint maxTextureSize; 44701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); 44801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mMaxTextureSize = maxTextureSize; 44901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 45001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mDebugEnabled = readDebugLevel() & kDebugCaches; 45101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 45201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 45301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 45401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Size management 45501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 45601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 45701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 45801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyuint32_t ShapeCache<Entry>::getSize() { 45901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return mSize; 46001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 46101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 46201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 46301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyuint32_t ShapeCache<Entry>::getMaxSize() { 46401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return mMaxSize; 46501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 46601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 46701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 46801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyvoid ShapeCache<Entry>::setMaxSize(uint32_t maxSize) { 46901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mMaxSize = maxSize; 47001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy while (mSize > mMaxSize) { 47101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache.removeOldest(); 47201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 47301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 47401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 47501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 47601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Callbacks 47701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 47801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 47901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 48001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyvoid ShapeCache<Entry>::operator()(Entry& path, PathTexture*& texture) { 48101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy removeTexture(texture); 48201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 48301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 48401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 48501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy// Caching 48601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy/////////////////////////////////////////////////////////////////////////////// 48701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 48801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 48901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyvoid ShapeCache<Entry>::removeTexture(PathTexture* texture) { 49001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy if (texture) { 49101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy const uint32_t size = texture->width * texture->height; 49201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mSize -= size; 49301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 494ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy SHAPE_LOGD("ShapeCache::callback: delete %s: name, size, mSize = %d, %d, %d", 495ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy mName, texture->id, size, mSize); 49601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy if (mDebugEnabled) { 4975baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Shape %s deleted, size = %d", mName, size); 49801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 49901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 50001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy glDeleteTextures(1, &texture->id); 50101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy delete texture; 50201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 50301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 50401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 505fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guyvoid computePathBounds(const SkPath* path, const SkPaint* paint, 506fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy float& left, float& top, float& offset, uint32_t& width, uint32_t& height); 507fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guyvoid computeBounds(const SkRect& bounds, const SkPaint* paint, 50833f6beb10f98e8ba96250e284876d607055d278dRomain Guy float& left, float& top, float& offset, uint32_t& width, uint32_t& height); 50933f6beb10f98e8ba96250e284876d607055d278dRomain Guy 510fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guystatic PathTexture* createTexture(float left, float top, float offset, 511fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy uint32_t width, uint32_t height, uint32_t id) { 512fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy PathTexture* texture = new PathTexture; 513fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy texture->left = left; 514fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy texture->top = top; 515fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy texture->offset = offset; 516fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy texture->width = width; 517fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy texture->height = height; 518fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy texture->generation = id; 519fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy return texture; 520fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy} 52198029c825b9234e6b90721d910cc180885fcab1dRomain Guy 522fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guytemplate<class Entry> 523fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guyvoid ShapeCache<Entry>::purgeCache(uint32_t width, uint32_t height) { 52401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy const uint32_t size = width * height; 52501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy // Don't even try to cache a bitmap that's bigger than the cache 52601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy if (size < mMaxSize) { 52701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy while (mSize + size > mMaxSize) { 52801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache.removeOldest(); 52901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 53001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 531fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy} 53201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 533fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guytemplate<class Entry> 534fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guyvoid ShapeCache<Entry>::initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) { 53501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bitmap.setConfig(SkBitmap::kA8_Config, width, height); 53601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bitmap.allocPixels(); 53701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy bitmap.eraseColor(0); 538fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy} 53901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 540fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guytemplate<class Entry> 541fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guyvoid ShapeCache<Entry>::initPaint(SkPaint& paint) { 54201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy // Make sure the paint is opaque, color, alpha, filter, etc. 54301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy // will be applied later when compositing the alpha8 texture 544fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy paint.setColor(0xff000000); 545fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy paint.setAlpha(255); 546fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy paint.setColorFilter(NULL); 547fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy paint.setMaskFilter(NULL); 548fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy paint.setShader(NULL); 54901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode); 550fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy SkSafeUnref(paint.setXfermode(mode)); 551fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy} 552fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 553fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guytemplate<class Entry> 554fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guybool ShapeCache<Entry>::checkTextureSize(uint32_t width, uint32_t height) { 555fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy if (width > mMaxTextureSize || height > mMaxTextureSize) { 556fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)", 557fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy mName, width, height, mMaxTextureSize, mMaxTextureSize); 558fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy return false; 559fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy } 560fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy return true; 561fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy} 562fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 563fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guytemplate<class Entry> 564fdd6fc1beb5076a630c7066b8b1731995636c09fRomain GuyPathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path, 565fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy const SkPaint* paint) { 566fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 567fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy float left, top, offset; 568fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy uint32_t width, height; 569fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy computePathBounds(path, paint, left, top, offset, width, height); 570fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 571fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy if (!checkTextureSize(width, height)) return NULL; 572fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 573fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy purgeCache(width, height); 574fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 575fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy SkBitmap bitmap; 576fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy initBitmap(bitmap, width, height); 577fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 578fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy SkPaint pathPaint(*paint); 579fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy initPaint(pathPaint); 58001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 58101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy SkCanvas canvas(bitmap); 58233f6beb10f98e8ba96250e284876d607055d278dRomain Guy canvas.translate(-left + offset, -top + offset); 58301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy canvas.drawPath(*path, pathPaint); 58401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 585fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy PathTexture* texture = createTexture(left, top, offset, width, height, path->getGenerationID()); 586fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy addTexture(entry, &bitmap, texture); 587fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 588fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy return texture; 589fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy} 590fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy 591fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guytemplate<class Entry> 592fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guyvoid ShapeCache<Entry>::addTexture(const Entry& entry, SkBitmap* bitmap, PathTexture* texture) { 593fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy generateTexture(*bitmap, texture); 59401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 595fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy uint32_t size = texture->width * texture->height; 59601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy if (size < mMaxSize) { 59701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mSize += size; 598ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy SHAPE_LOGD("ShapeCache::get: create %s: name, size, mSize = %d, %d, %d", 599ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy mName, texture->id, size, mSize); 60001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy if (mDebugEnabled) { 6015baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Shape %s created, size = %d", mName, size); 60201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 60301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache.put(entry, texture); 60401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } else { 60501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy texture->cleanup = true; 60601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 60701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 60801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 60901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 61001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyvoid ShapeCache<Entry>::clear() { 61101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy mCache.clear(); 61201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 61301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 61401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guytemplate<class Entry> 61501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guyvoid ShapeCache<Entry>::generateTexture(SkBitmap& bitmap, Texture* texture) { 61601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy SkAutoLockPixels alp(bitmap); 61701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy if (!bitmap.readyToDraw()) { 6183762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Cannot generate texture from bitmap"); 61901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy return; 62001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy } 62101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 62201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy glGenTextures(1, &texture->id); 62301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 62401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy glBindTexture(GL_TEXTURE_2D, texture->id); 62501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy // Textures are Alpha8 62601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 62701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 62801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy texture->blend = true; 62901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0, 63001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels()); 63101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 632d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy texture->setFilter(GL_LINEAR); 633d21b6e1fe337b35f62cf2028e9bd0637fd009a75Romain Guy texture->setWrap(GL_CLAMP_TO_EDGE); 63401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy} 63501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 63601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // namespace uirenderer 63701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // namespace android 63801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy 63901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#endif // ANDROID_HWUI_SHAPE_CACHE_H 640