AssetAtlas.cpp revision 7f6d6b0370df4b5a9e0f45bffc31ea6caeeb509d
13b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/* 23b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Copyright (C) 2013 The Android Open Source Project 33b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * 43b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 53b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * you may not use this file except in compliance with the License. 63b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * You may obtain a copy of the License at 73b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * 83b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 93b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * 103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Unless required by applicable law or agreed to in writing, software 113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * See the License for the specific language governing permissions and 143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * limitations under the License. 153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1755b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy#define LOG_TAG "OpenGLRenderer" 1855b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy 193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "AssetAtlas.h" 208aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy#include "Caches.h" 213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <GLES2/gl2ext.h> 233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android { 253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace uirenderer { 263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Lifecycle 293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) { 32877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy if (mImage) { 333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return; 343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 36877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy mImage = new Image(buffer); 373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 38a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy if (mImage->getTexture()) { 398aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy Caches& caches = Caches::getInstance(); 408aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy 418aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy mTexture = new Texture(caches); 42a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture->id = mImage->getTexture(); 43a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture->width = buffer->getWidth(); 44a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture->height = buffer->getHeight(); 453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 468aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy createEntries(caches, map, count); 47877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy } else { 48d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy ALOGW("Could not create atlas image"); 49d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy 50877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy delete mImage; 51d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy mImage = NULL; 52a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture = NULL; 533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 5455b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy 5555b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy mGenerationId++; 563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid AssetAtlas::terminate() { 59877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy if (mImage) { 60877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy delete mImage; 61d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy mImage = NULL; 623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 63a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy delete mTexture; 64a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture = NULL; 65a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy for (size_t i = 0; i < mEntries.size(); i++) { 673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy delete mEntries.valueAt(i); 683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mEntries.clear(); 703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Entries 753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain GuyAssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const { 783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t index = mEntries.indexOfKey(bitmap); 793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return index >= 0 ? mEntries.valueAt(index) : NULL; 803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain GuyTexture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const { 833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t index = mEntries.indexOfKey(bitmap); 84a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy return index >= 0 ? mEntries.valueAt(index)->texture : NULL; 853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/** 88a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy * Delegates changes to wrapping and filtering to the base atlas texture 89a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy * instead of applying the changes to the virtual textures. 90a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy */ 91a404e16e4933857464046d763ed7629cd0c86cbfRomain Guystruct DelegateTexture: public Texture { 928aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { } 93a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 94a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, 95a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy bool force = false, GLenum renderTarget = GL_TEXTURE_2D) { 96a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget); 97a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy } 98a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 99a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, 100a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy bool force = false, GLenum renderTarget = GL_TEXTURE_2D) { 101a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget); 102a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy } 1037f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy 104a404e16e4933857464046d763ed7629cd0c86cbfRomain Guyprivate: 105a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy Texture* const mDelegate; 106a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy}; // struct DelegateTexture 107a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 108a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy/** 1093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * TODO: This method does not take the rotation flag into account 1103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 1118aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyvoid AssetAtlas::createEntries(Caches& caches, int* map, int count) { 112a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy const float width = float(mTexture->width); 113a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy const float height = float(mTexture->height); 114a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy for (int i = 0; i < count; ) { 1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkBitmap* bitmap = (SkBitmap*) map[i++]; 1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int x = map[i++]; 1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int y = map[i++]; 1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy bool rotated = map[i++] > 0; 1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy // Bitmaps should never be null, we're just extra paranoid 1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!bitmap) continue; 1233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const UvMapper mapper( 125a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy x / width, (x + bitmap->width()) / width, 126a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy y / height, (y + bitmap->height()) / height); 127a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 1288aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy Texture* texture = new DelegateTexture(caches, mTexture); 129a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->id = mTexture->id; 130a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->blend = !bitmap->isOpaque(); 131a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->width = bitmap->width(); 132a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->height = bitmap->height(); 1337f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy 1347f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this); 135a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->uvMapper = &entry->uvMapper; 1363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mEntries.add(entry->bitmap, entry); 1383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; // namespace uirenderer 1423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; // namespace android 143