11e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy/*
21e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Copyright (C) 2010 The Android Open Source Project
31e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy *
41e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
51e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * you may not use this file except in compliance with the License.
61e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * You may obtain a copy of the License at
71e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy *
81e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
91e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy *
101e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * Unless required by applicable law or agreed to in writing, software
111e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
121e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * See the License for the specific language governing permissions and
141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy * limitations under the License.
151e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy */
161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#define LOG_TAG "OpenGLRenderer"
181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
19059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy#include <utils/JenkinsHash.h>
20059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
218aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy#include "Caches.h"
22c9855a53edfac818dc68714557185977556f849dRomain Guy#include "Debug.h"
231e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy#include "TextDropShadowCache.h"
24b45c0c9774bd19a9dbe77d149abae4e124b08bf6Romain Guy#include "Properties.h"
251e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
261e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace android {
271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guynamespace uirenderer {
281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
30059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy// Cache support
31059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy///////////////////////////////////////////////////////////////////////////////
32059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
33059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyhash_t ShadowText::hash() const {
3469fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy    uint32_t charCount = len / sizeof(char16_t);
35059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    uint32_t hash = JenkinsHashMix(0, len);
36059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    hash = JenkinsHashMix(hash, android::hash_type(radius));
37059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    hash = JenkinsHashMix(hash, android::hash_type(textSize));
38059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    hash = JenkinsHashMix(hash, android::hash_type(typeface));
39059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    hash = JenkinsHashMix(hash, flags);
40059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    hash = JenkinsHashMix(hash, android::hash_type(italicStyle));
41059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    hash = JenkinsHashMix(hash, android::hash_type(scaleX));
4269fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy    if (text) {
4369fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy        hash = JenkinsHashMixShorts(hash, text, charCount);
4469fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy    }
4569fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy    if (positions) {
4669fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy        for (uint32_t i = 0; i < charCount * 2; i++) {
4769fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy            hash = JenkinsHashMix(hash, android::hash_type(positions[i]));
4869fcbccf476ffc55af4da4dfedc72c3de8f91ce8Romain Guy        }
49059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    }
50059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    return JenkinsHashWhiten(hash);
51059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy}
52059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
53059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyint ShadowText::compare(const ShadowText& lhs, const ShadowText& rhs) {
54059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    int deltaInt = int(lhs.len) - int(rhs.len);
55059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (deltaInt != 0) return deltaInt;
56059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
57059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    deltaInt = lhs.flags - rhs.flags;
58059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (deltaInt != 0) return deltaInt;
59059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
60059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.radius < rhs.radius) return -1;
61059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.radius > rhs.radius) return +1;
62059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
63059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.typeface < rhs.typeface) return -1;
64059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.typeface > rhs.typeface) return +1;
65059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
66059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.textSize < rhs.textSize) return -1;
67059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.textSize > rhs.textSize) return +1;
68059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
69059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.italicStyle < rhs.italicStyle) return -1;
70059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.italicStyle > rhs.italicStyle) return +1;
71059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
72059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.scaleX < rhs.scaleX) return -1;
73059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.scaleX > rhs.scaleX) return +1;
74059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
75059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.text != rhs.text) {
76059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        if (!lhs.text) return -1;
77059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        if (!rhs.text) return +1;
78059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
79059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        deltaInt = memcmp(lhs.text, rhs.text, lhs.len);
80059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        if (deltaInt != 0) return deltaInt;
81059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    }
82059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
83059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    if (lhs.positions != rhs.positions) {
84059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        if (!lhs.positions) return -1;
85059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        if (!rhs.positions) return +1;
86059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
87059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        return memcmp(lhs.positions, rhs.positions, lhs.len << 2);
88059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    }
89059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
90059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy    return 0;
91059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy}
92059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy
93059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy///////////////////////////////////////////////////////////////////////////////
941e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Constructors/destructor
951e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
961e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
97fb8b763f762ae21923c58d64caa729b012f40e05Romain GuyTextDropShadowCache::TextDropShadowCache():
98059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        mCache(LruCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity),
99fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        mSize(0), mMaxSize(MB(DEFAULT_DROP_SHADOW_CACHE_SIZE)) {
100fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    char property[PROPERTY_VALUE_MAX];
101fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    if (property_get(PROPERTY_DROP_SHADOW_CACHE_SIZE, property, NULL) > 0) {
102c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Setting drop shadow cache size to %sMB", property);
103fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        setMaxSize(MB(atof(property)));
104fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    } else {
105c9855a53edfac818dc68714557185977556f849dRomain Guy        INIT_LOGD("  Using default drop shadow cache size of %.2fMB",
106c9855a53edfac818dc68714557185977556f849dRomain Guy                DEFAULT_DROP_SHADOW_CACHE_SIZE);
107fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    }
108fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
10925dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy    init();
110fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy}
111fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
1121e45aae5de003657e5d18f74d34998f5de5db5b7Romain GuyTextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize):
113059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        mCache(LruCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity),
1141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        mSize(0), mMaxSize(maxByteSize) {
11525dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy    init();
1161e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1181e45aae5de003657e5d18f74d34998f5de5db5b7Romain GuyTextDropShadowCache::~TextDropShadowCache() {
1191e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    mCache.clear();
1201e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1211e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
12225dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guyvoid TextDropShadowCache::init() {
12325dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy    mCache.setOnEntryRemovedListener(this);
12425dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy    mDebugEnabled = readDebugLevel() & kDebugMoreCaches;
12525dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy}
12625dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy
1271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
1281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Size management
1291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
1301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyuint32_t TextDropShadowCache::getSize() {
1321e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    return mSize;
1331e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1341e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1351e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyuint32_t TextDropShadowCache::getMaxSize() {
1361e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    return mMaxSize;
1371e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1381e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1391e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyvoid TextDropShadowCache::setMaxSize(uint32_t maxSize) {
1401e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    mMaxSize = maxSize;
1411e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    while (mSize > mMaxSize) {
1421e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        mCache.removeOldest();
1431e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    }
1441e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1451e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1461e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
1471e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Callbacks
1481e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
1491e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
150e63f7c622a2086aefa80983c6f41b74fb166bb42Chris Craikvoid TextDropShadowCache::operator()(ShadowText&, ShadowTexture*& texture) {
1511e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    if (texture) {
15225dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy        mSize -= texture->bitmapSize;
15325dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy
15425dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy        if (mDebugEnabled) {
1555baa3a62a97544669fba6d65a11c07f252e654ddSteve Block            ALOGD("Shadow texture deleted, size = %d", texture->bitmapSize);
15625dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy        }
157f70a7e34953438dd70573dbb6fd3dd34a1bce831Romain Guy
158be1b127c7bec252e0c6ab0e06ed6babed07d496fRomain Guy        texture->deleteTexture();
1591e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        delete texture;
1601e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    }
1611e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1621e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1631e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
1641e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy// Caching
1651e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy///////////////////////////////////////////////////////////////////////////////
1661e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1671e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guyvoid TextDropShadowCache::clear() {
1681e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    mCache.clear();
1691e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
1701e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
171d218a92c0afb8c0d98135b20b52ac87236e1c935Chris CraikShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const char* text, uint32_t len,
172059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy        int numGlyphs, float radius, const float* positions) {
173416a847633680d94efb926837efdc18726d54918Raph Levien    ShadowText entry(paint, radius, len, text, positions);
1741e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    ShadowTexture* texture = mCache.get(entry);
1751e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1761e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    if (!texture) {
1778b4072d3fb9bb49d774d97689a065204beca1752Raph Levien        SkPaint paintCopy(*paint);
1788b4072d3fb9bb49d774d97689a065204beca1752Raph Levien        paintCopy.setTextAlign(SkPaint::kLeft_Align);
1798b4072d3fb9bb49d774d97689a065204beca1752Raph Levien        FontRenderer::DropShadow shadow = mRenderer->renderDropShadow(&paintCopy, text, 0,
180416a847633680d94efb926837efdc18726d54918Raph Levien                len, numGlyphs, radius, positions);
1811e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
182cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        if (!shadow.image) {
183cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy            return NULL;
184cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy        }
185cf51a4199835e9604aa4c8b3854306f8fbabbf33Romain Guy
1868aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        Caches& caches = Caches::getInstance();
1878aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy
1888aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        texture = new ShadowTexture(caches);
1891e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        texture->left = shadow.penX;
1901e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        texture->top = shadow.penY;
1911e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        texture->width = shadow.width;
1921e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        texture->height = shadow.height;
1931e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        texture->generation = 0;
1941e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        texture->blend = true;
1951e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
1961e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        const uint32_t size = shadow.width * shadow.height;
19725dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy        texture->bitmapSize = size;
19825dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy
1991e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        // Don't even try to cache a bitmap that's bigger than the cache
2001e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        if (size < mMaxSize) {
2011e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            while (mSize + size > mMaxSize) {
2021e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy                mCache.removeOldest();
2031e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            }
2041e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        }
2051e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2061e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        glGenTextures(1, &texture->id);
2071e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2088aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy        caches.bindTexture(texture->id);
2091e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        // Textures are Alpha8
2101e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
2111e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2121e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
2131e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy                GL_ALPHA, GL_UNSIGNED_BYTE, shadow.image);
2141e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
21539d252a6632d057d5077f7eaf1b8ed7a142f3397Romain Guy        texture->setFilter(GL_LINEAR);
21639d252a6632d057d5077f7eaf1b8ed7a142f3397Romain Guy        texture->setWrap(GL_CLAMP_TO_EDGE);
2171e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2181e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        if (size < mMaxSize) {
21925dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy            if (mDebugEnabled) {
2205baa3a62a97544669fba6d65a11c07f252e654ddSteve Block                ALOGD("Shadow texture created, size = %d", texture->bitmapSize);
22125dc3a7dbac2f90f5144035e9c8ed99c09cc3132Romain Guy            }
222321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy
223321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy            entry.copyTextLocally();
224321dce646dc3c2ecfbd72a693d8d9294a6119736Romain Guy
2251e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            mSize += size;
2261e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            mCache.put(entry, texture);
2271e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        } else {
2281e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy            texture->cleanup = true;
2291e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        }
2301e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2311e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy        // Cleanup shadow
23215641a6181cdaac2aadf07585de66483b4b7ae6bBen Cheng        free(shadow.image);
2331e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    }
2341e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2351e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy    return texture;
2361e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}
2371e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy
2381e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace uirenderer
2391e45aae5de003657e5d18f74d34998f5de5db5b7Romain Guy}; // namespace android
240