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#define LOG_TAG "OpenGLRenderer"
1801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
1901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy#include "ShapeCache.h"
2001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
2101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guynamespace android {
2201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guynamespace uirenderer {
2301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
24ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy///////////////////////////////////////////////////////////////////////////////
25ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy// Rounded rects
26ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy///////////////////////////////////////////////////////////////////////////////
27ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy
28ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain GuyRoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>(
29ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy        "round rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
3001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
3101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
3201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain GuyPathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
3301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        float rx, float ry, SkPaint* paint) {
3401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    RoundRectShapeCacheEntry entry(width, height, rx, ry, paint);
3501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    PathTexture* texture = get(entry);
3601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
3701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    if (!texture) {
3801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        SkPath path;
3901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        SkRect r;
4001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        r.set(0.0f, 0.0f, width, height);
4101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
4201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
4301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        texture = addTexture(entry, &path, paint);
4401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    }
4501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
4601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    return texture;
4701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
4801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
49ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy///////////////////////////////////////////////////////////////////////////////
50ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy// Circles
51ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy///////////////////////////////////////////////////////////////////////////////
52ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy
53ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain GuyCircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>(
54ff26a0c1c905dc1ec53b1bab860b80f2976d59beRomain Guy        "circle", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
5501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
5601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
5701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain GuyPathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
5801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    CircleShapeCacheEntry entry(radius, paint);
5901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    PathTexture* texture = get(entry);
6001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
6101d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    if (!texture) {
6201d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        SkPath path;
6301d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
6401d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
6501d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy        texture = addTexture(entry, &path, paint);
6601d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    }
6701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
6801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy    return texture;
6901d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}
7001d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy
71c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy///////////////////////////////////////////////////////////////////////////////
72c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy// Ovals
73c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy///////////////////////////////////////////////////////////////////////////////
74c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
75c1cd9ba335b293f11e1082447ef08e474710a05fRomain GuyOvalShapeCache::OvalShapeCache(): ShapeCache<OvalShapeCacheEntry>(
76c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        "oval", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
77c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
78c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
79c1cd9ba335b293f11e1082447ef08e474710a05fRomain GuyPathTexture* OvalShapeCache::getOval(float width, float height, SkPaint* paint) {
80c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    OvalShapeCacheEntry entry(width, height, paint);
81c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    PathTexture* texture = get(entry);
82c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
83c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    if (!texture) {
84c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        SkPath path;
85c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        SkRect r;
86c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        r.set(0.0f, 0.0f, width, height);
87c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        path.addOval(r, SkPath::kCW_Direction);
88c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
89c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        texture = addTexture(entry, &path, paint);
90c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    }
91c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
92c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    return texture;
93c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
94c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
95c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy///////////////////////////////////////////////////////////////////////////////
96c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy// Rects
97c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy///////////////////////////////////////////////////////////////////////////////
98c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
99c1cd9ba335b293f11e1082447ef08e474710a05fRomain GuyRectShapeCache::RectShapeCache(): ShapeCache<RectShapeCacheEntry>(
100c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy        "rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
101c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
102c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
103c1cd9ba335b293f11e1082447ef08e474710a05fRomain GuyPathTexture* RectShapeCache::getRect(float width, float height, SkPaint* paint) {
104c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    RectShapeCacheEntry entry(width, height, paint);
105c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    PathTexture* texture = get(entry);
106c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
107c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    if (!texture) {
108fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        SkRect bounds;
109fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        bounds.set(0.0f, 0.0f, width, height);
110c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
111fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        float left, top, offset;
112fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        uint32_t rectWidth, rectHeight;
113fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        computeBounds(bounds, paint, left, top, offset, rectWidth, rectHeight);
114fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy
115fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        if (!checkTextureSize(rectWidth, rectHeight)) return NULL;
116fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy
117fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        purgeCache(rectWidth, rectHeight);
118fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy
119fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        SkBitmap bitmap;
120fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        initBitmap(bitmap, rectWidth, rectHeight);
121fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy
122fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        SkPaint pathPaint(*paint);
123fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        initPaint(pathPaint);
124fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy
125fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        SkCanvas canvas(bitmap);
126fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        canvas.translate(-left + offset, -top + offset);
127fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        canvas.drawRect(bounds, pathPaint);
128fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy
129fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        texture = createTexture(0, 0, offset, rectWidth, rectHeight, 0);
130fdd6fc1beb5076a630c7066b8b1731995636c09fRomain Guy        addTexture(entry, &bitmap, texture);
131c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    }
132c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
133c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy    return texture;
134c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy}
135c1cd9ba335b293f11e1082447ef08e474710a05fRomain Guy
1368b2f5267f16c295f12faab810527cd6311997e34Romain Guy///////////////////////////////////////////////////////////////////////////////
1378b2f5267f16c295f12faab810527cd6311997e34Romain Guy// Arcs
1388b2f5267f16c295f12faab810527cd6311997e34Romain Guy///////////////////////////////////////////////////////////////////////////////
1398b2f5267f16c295f12faab810527cd6311997e34Romain Guy
1408b2f5267f16c295f12faab810527cd6311997e34Romain GuyArcShapeCache::ArcShapeCache(): ShapeCache<ArcShapeCacheEntry>(
1418b2f5267f16c295f12faab810527cd6311997e34Romain Guy        "arc", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
1428b2f5267f16c295f12faab810527cd6311997e34Romain Guy}
1438b2f5267f16c295f12faab810527cd6311997e34Romain Guy
1448b2f5267f16c295f12faab810527cd6311997e34Romain GuyPathTexture* ArcShapeCache::getArc(float width, float height,
1458b2f5267f16c295f12faab810527cd6311997e34Romain Guy        float startAngle, float sweepAngle, bool useCenter, SkPaint* paint) {
1468b2f5267f16c295f12faab810527cd6311997e34Romain Guy    ArcShapeCacheEntry entry(width, height, startAngle, sweepAngle, useCenter, paint);
1478b2f5267f16c295f12faab810527cd6311997e34Romain Guy    PathTexture* texture = get(entry);
1488b2f5267f16c295f12faab810527cd6311997e34Romain Guy
1498b2f5267f16c295f12faab810527cd6311997e34Romain Guy    if (!texture) {
1508b2f5267f16c295f12faab810527cd6311997e34Romain Guy        SkPath path;
1518b2f5267f16c295f12faab810527cd6311997e34Romain Guy        SkRect r;
1528b2f5267f16c295f12faab810527cd6311997e34Romain Guy        r.set(0.0f, 0.0f, width, height);
1538b2f5267f16c295f12faab810527cd6311997e34Romain Guy        if (useCenter) {
1548b2f5267f16c295f12faab810527cd6311997e34Romain Guy            path.moveTo(r.centerX(), r.centerY());
1558b2f5267f16c295f12faab810527cd6311997e34Romain Guy        }
1568b2f5267f16c295f12faab810527cd6311997e34Romain Guy        path.arcTo(r, startAngle, sweepAngle, !useCenter);
1578b2f5267f16c295f12faab810527cd6311997e34Romain Guy        if (useCenter) {
1588b2f5267f16c295f12faab810527cd6311997e34Romain Guy            path.close();
1598b2f5267f16c295f12faab810527cd6311997e34Romain Guy        }
1608b2f5267f16c295f12faab810527cd6311997e34Romain Guy
1618b2f5267f16c295f12faab810527cd6311997e34Romain Guy        texture = addTexture(entry, &path, paint);
1628b2f5267f16c295f12faab810527cd6311997e34Romain Guy    }
1638b2f5267f16c295f12faab810527cd6311997e34Romain Guy
1648b2f5267f16c295f12faab810527cd6311997e34Romain Guy    return texture;
1658b2f5267f16c295f12faab810527cd6311997e34Romain Guy}
1668b2f5267f16c295f12faab810527cd6311997e34Romain Guy
16701d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // namespace uirenderer
16801d58e43ede5ca98cbebdd166f9b0c545032c01bRomain Guy}; // namespace android
169