TextureCache.cpp revision 5b3b35296e8b2c8d3f07d32bb645d5414db41a1d
1ce0537b80087a6225273040a987414b1dd081aa0Romain Guy/*
2ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Copyright (C) 2010 The Android Open Source Project
3ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *
4ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
5ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * you may not use this file except in compliance with the License.
6ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * You may obtain a copy of the License at
7ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *
8ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
9ce0537b80087a6225273040a987414b1dd081aa0Romain Guy *
10ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * Unless required by applicable law or agreed to in writing, software
11ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
12ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * See the License for the specific language governing permissions and
14ce0537b80087a6225273040a987414b1dd081aa0Romain Guy * limitations under the License.
15ce0537b80087a6225273040a987414b1dd081aa0Romain Guy */
16ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
17121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy#define LOG_TAG "OpenGLRenderer"
18121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
19ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include <GLES2/gl2.h>
20ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
217adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy#include <SkCanvas.h>
227adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy
239aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy#include <utils/threads.h>
249aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy
25ce0537b80087a6225273040a987414b1dd081aa0Romain Guy#include "TextureCache.h"
26fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy#include "Properties.h"
27ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
28ce0537b80087a6225273040a987414b1dd081aa0Romain Guynamespace android {
29ce0537b80087a6225273040a987414b1dd081aa0Romain Guynamespace uirenderer {
30ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
31121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
32121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy// Constructors/destructor
33121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
34121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
35fb8b763f762ae21923c58d64caa729b012f40e05Romain GuyTextureCache::TextureCache():
36fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
37fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        mSize(0), mMaxSize(MB(DEFAULT_TEXTURE_CACHE_SIZE)) {
38fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    char property[PROPERTY_VALUE_MAX];
39fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    if (property_get(PROPERTY_TEXTURE_CACHE_SIZE, property, NULL) > 0) {
40fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        LOGD("  Setting texture cache size to %sMB", property);
41fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        setMaxSize(MB(atof(property)));
42fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    } else {
43fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy        LOGD("  Using default texture cache size of %.2fMB", DEFAULT_TEXTURE_CACHE_SIZE);
44fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    }
45fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
46fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    init();
47fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy}
48fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
497d139ba2c331f11e9b485753cc727a0ff202f2a4Romain GuyTextureCache::TextureCache(uint32_t maxByteSize):
506c81893c626499e58c8eeb20d6c35ec4e1ce808bRomain Guy        mCache(GenerationCache<SkBitmap*, Texture*>::kUnlimitedCapacity),
51121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        mSize(0), mMaxSize(maxByteSize) {
52fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    init();
53ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
54ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
55ce0537b80087a6225273040a987414b1dd081aa0Romain GuyTextureCache::~TextureCache() {
569aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    Mutex::Autolock _l(mLock);
57ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    mCache.clear();
58ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
59ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
60fb8b763f762ae21923c58d64caa729b012f40e05Romain Guyvoid TextureCache::init() {
61fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    mCache.setOnEntryRemovedListener(this);
62fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
63fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
64fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy    LOGD("    Maximum texture dimension is %d pixels", mMaxTextureSize);
65fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy}
66fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy
67121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
68121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy// Size management
69121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
70121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
717d139ba2c331f11e9b485753cc727a0ff202f2a4Romain Guyuint32_t TextureCache::getSize() {
729aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    Mutex::Autolock _l(mLock);
73121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    return mSize;
74121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy}
75121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
767d139ba2c331f11e9b485753cc727a0ff202f2a4Romain Guyuint32_t TextureCache::getMaxSize() {
779aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    Mutex::Autolock _l(mLock);
78121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    return mMaxSize;
79121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy}
80121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
817d139ba2c331f11e9b485753cc727a0ff202f2a4Romain Guyvoid TextureCache::setMaxSize(uint32_t maxSize) {
829aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    Mutex::Autolock _l(mLock);
83121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    mMaxSize = maxSize;
84121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    while (mSize > mMaxSize) {
85121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        mCache.removeOldest();
86121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    }
87121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy}
88121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
89121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
90121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy// Callbacks
91121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
92121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
93dda570201ac851dd85af3861f7e575721d3345daRomain Guyvoid TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) {
949aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    // This will be called already locked
95121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    if (texture) {
969aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy        mSize -= texture->bitmapSize;
97d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase        TEXTURE_LOGD("TextureCache::callback: removed size, mSize = %d, %d",
98d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase                texture->bitmapSize, mSize);
99121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        glDeleteTextures(1, &texture->id);
100121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        delete texture;
101ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    }
102ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
103ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
104121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
105121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy// Caching
106121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy///////////////////////////////////////////////////////////////////////////////
107121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
108ce0537b80087a6225273040a987414b1dd081aa0Romain GuyTexture* TextureCache::get(SkBitmap* bitmap) {
109a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy    mLock.lock();
110ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    Texture* texture = mCache.get(bitmap);
111a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy    mLock.unlock();
112a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy
113ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    if (!texture) {
1149cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy        if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
1159cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy            LOGW("Bitmap too large to be uploaded into a texture");
1169cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy            return NULL;
1179cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy        }
1189cccc2b9bdd4850a3f9679569aaec3ab98477a5dRomain Guy
1197d139ba2c331f11e9b485753cc727a0ff202f2a4Romain Guy        const uint32_t size = bitmap->rowBytes() * bitmap->height();
120121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        // Don't even try to cache a bitmap that's bigger than the cache
121121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        if (size < mMaxSize) {
122a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy            mLock.lock();
123121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy            while (mSize + size > mMaxSize) {
124121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy                mCache.removeOldest();
125121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy            }
126a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy            mLock.unlock();
127121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        }
128121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
129364703c6fa4aa1a7d2ef5b0c048ea2a0d57a4c40Romain Guy        texture = new Texture;
1309aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy        texture->bitmapSize = size;
131c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy        generateTexture(bitmap, texture, false);
132121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy
133121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        if (size < mMaxSize) {
134a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy            mLock.lock();
135121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy            mSize += size;
136d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase            TEXTURE_LOGD("TextureCache::get: create texture(0x%p): size, mSize = %d, %d",
137d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase                     bitmap, size, mSize);
138121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy            mCache.put(bitmap, texture);
139a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy            mLock.unlock();
14022158e139a3d6c6a9787ca0de224e9368f643284Romain Guy        } else {
14122158e139a3d6c6a9787ca0de224e9368f643284Romain Guy            texture->cleanup = true;
142121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy        }
143fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy    } else if (bitmap->getGenerationID() != texture->generation) {
144fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy        generateTexture(bitmap, texture, true);
145ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    }
14622158e139a3d6c6a9787ca0de224e9368f643284Romain Guy
147ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    return texture;
148ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
149ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
150121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guyvoid TextureCache::remove(SkBitmap* bitmap) {
1519aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    Mutex::Autolock _l(mLock);
152121e2242565d5f09ad83a2d33ecd2225838802c5Romain Guy    mCache.remove(bitmap);
153ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
154ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
155ce0537b80087a6225273040a987414b1dd081aa0Romain Guyvoid TextureCache::clear() {
1569aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy    Mutex::Autolock _l(mLock);
157ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    mCache.clear();
158d98aa2de9ab18e09c2be1997f41212740f51f6e6Chet Haase    TEXTURE_LOGD("TextureCache:clear(), miSize = %d", mSize);
159ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
160ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
161fe8809471a40cac8acc984adfa51c39e13e83947Romain Guyvoid TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) {
162c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    SkAutoLockPixels alp(*bitmap);
1639aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy
164c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    if (!bitmap->readyToDraw()) {
165c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy        LOGE("Cannot generate texture from bitmap");
166c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy        return;
167c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    }
168c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy
16929d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy    const bool resize = !regenerate || bitmap->width() != int(texture->width) ||
17029d8997bd43b7c4ad37fc3d6f91eaafa74913c88Romain Guy            bitmap->height() != int(texture->height);
171fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy
1728c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    if (!regenerate) {
173fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy        glGenTextures(1, &texture->id);
174fe8809471a40cac8acc984adfa51c39e13e83947Romain Guy    }
175ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
1768c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    texture->generation = bitmap->getGenerationID();
1778c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    texture->width = bitmap->width();
1788c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    texture->height = bitmap->height();
1798c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy
180ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    glBindTexture(GL_TEXTURE_2D, texture->id);
181c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
182ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
183ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    switch (bitmap->getConfig()) {
184bd0e6aa0ff0bd8b376772c3e23513a6021bdda87Romain Guy    case SkBitmap::kA8_Config:
1859aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4Romain Guy        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1868c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        uploadToTexture(resize, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height,
1878c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy                GL_UNSIGNED_BYTE, bitmap->getPixels());
1888c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        texture->blend = true;
189bd0e6aa0ff0bd8b376772c3e23513a6021bdda87Romain Guy        break;
190ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    case SkBitmap::kRGB_565_Config:
1918c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        uploadToTexture(resize, GL_RGB, bitmap->rowBytesAsPixels(), texture->height,
1928c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy                GL_UNSIGNED_SHORT_5_6_5, bitmap->getPixels());
193c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy        texture->blend = false;
194ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        break;
195ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    case SkBitmap::kARGB_8888_Config:
1968c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        uploadToTexture(resize, GL_RGBA, bitmap->rowBytesAsPixels(), texture->height,
1978c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy                GL_UNSIGNED_BYTE, bitmap->getPixels());
198e9e7fd0813f1485d20c6cd0014d59aff53c35d84Romain Guy        // Do this after calling getPixels() to make sure Skia's deferred
199e9e7fd0813f1485d20c6cd0014d59aff53c35d84Romain Guy        // decoding happened
200e9e7fd0813f1485d20c6cd0014d59aff53c35d84Romain Guy        texture->blend = !bitmap->isOpaque();
201ce0537b80087a6225273040a987414b1dd081aa0Romain Guy        break;
2027adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    case SkBitmap::kIndex8_Config:
2035b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
2047adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy        texture->blend = false;
2057adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy        break;
2065b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy    case SkBitmap::kARGB_4444_Config:
2075b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        uploadLoFiTexture(resize, bitmap, texture->width, texture->height);
2085b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        texture->blend = true;
2095b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy        break;
210364703c6fa4aa1a7d2ef5b0c048ea2a0d57a4c40Romain Guy    default:
2117adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy        LOGW("Unsupported bitmap config: %d", bitmap->getConfig());
212364703c6fa4aa1a7d2ef5b0c048ea2a0d57a4c40Romain Guy        break;
213ce0537b80087a6225273040a987414b1dd081aa0Romain Guy    }
214ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
215c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
216c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2178ba548f81d1ab5f1750cbf86098c4a14e0b8beadRomain Guy
218c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
219c1396e93b6a5286a5183c00c781b62e940a12c1fRomain Guy    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
220ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}
221ce0537b80087a6225273040a987414b1dd081aa0Romain Guy
2225b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guyvoid TextureCache::uploadLoFiTexture(bool resize, SkBitmap* bitmap,
2237adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy        uint32_t width, uint32_t height) {
2247adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    SkBitmap rgbaBitmap;
2257adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
2267adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    rgbaBitmap.allocPixels();
2277adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    rgbaBitmap.eraseColor(0);
2287adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy
2297adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    SkCanvas canvas(rgbaBitmap);
2307adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);
2317adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy
2327adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy    uploadToTexture(resize, GL_RGBA, rgbaBitmap.rowBytesAsPixels(), height,
2337adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy            GL_UNSIGNED_BYTE, rgbaBitmap.getPixels());
2347adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy}
2357adaf3d1aa18c7e521f7154e545fe52d329763c3Romain Guy
2368c749f87d29e1a363ddf9027c3a51753c612d510Romain Guyvoid TextureCache::uploadToTexture(bool resize, GLenum format, GLsizei width, GLsizei height,
2378c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        GLenum type, const GLvoid * data) {
2388c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    if (resize) {
2398c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, data);
2408c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    } else {
2418c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, data);
2428c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy    }
2438c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy}
2448c749f87d29e1a363ddf9027c3a51753c612d510Romain Guy
245ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}; // namespace uirenderer
246ce0537b80087a6225273040a987414b1dd081aa0Romain Guy}; // namespace android
247