AssetAtlas.cpp revision a404e16e4933857464046d763ed7629cd0c86cbf
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 173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "AssetAtlas.h" 183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <GLES2/gl2ext.h> 203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android { 223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace uirenderer { 233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Lifecycle 263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) { 29877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy if (mImage) { 303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return; 313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 33877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy mImage = new Image(buffer); 343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 35a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy if (mImage->getTexture()) { 36a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture = new Texture(); 37a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture->id = mImage->getTexture(); 38a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture->width = buffer->getWidth(); 39a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture->height = buffer->getHeight(); 403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 41877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy createEntries(map, count); 42877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy } else { 43d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy ALOGW("Could not create atlas image"); 44d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy 45877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy delete mImage; 46d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy mImage = NULL; 47a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture = NULL; 483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid AssetAtlas::terminate() { 52877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy if (mImage) { 53877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy delete mImage; 54d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy mImage = NULL; 553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 56a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy delete mTexture; 57a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mTexture = NULL; 58a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy for (size_t i = 0; i < mEntries.size(); i++) { 603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy delete mEntries.valueAt(i); 613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mEntries.clear(); 633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Entries 683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 693b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 703b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain GuyAssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const { 713b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t index = mEntries.indexOfKey(bitmap); 723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return index >= 0 ? mEntries.valueAt(index) : NULL; 733b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 743b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 753b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain GuyTexture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const { 763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t index = mEntries.indexOfKey(bitmap); 77a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy return index >= 0 ? mEntries.valueAt(index)->texture : NULL; 783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/** 81a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy * Delegates changes to wrapping and filtering to the base atlas texture 82a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy * instead of applying the changes to the virtual textures. 83a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy */ 84a404e16e4933857464046d763ed7629cd0c86cbfRomain Guystruct DelegateTexture: public Texture { 85a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy DelegateTexture(Texture* delegate): Texture(), mDelegate(delegate) { } 86a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 87a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, 88a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy bool force = false, GLenum renderTarget = GL_TEXTURE_2D) { 89a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget); 90a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy } 91a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 92a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, 93a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy bool force = false, GLenum renderTarget = GL_TEXTURE_2D) { 94a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget); 95a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy } 96a404e16e4933857464046d763ed7629cd0c86cbfRomain Guyprivate: 97a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy Texture* const mDelegate; 98a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy}; // struct DelegateTexture 99a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 100a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy/** 1013b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * TODO: This method does not take the rotation flag into account 1023b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 1033b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid AssetAtlas::createEntries(int* map, int count) { 104a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy const float width = float(mTexture->width); 105a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy const float height = float(mTexture->height); 106a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 1073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy for (int i = 0; i < count; ) { 1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy SkBitmap* bitmap = (SkBitmap*) map[i++]; 1093b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int x = map[i++]; 1103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy int y = map[i++]; 1113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy bool rotated = map[i++] > 0; 1123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy // Bitmaps should never be null, we're just extra paranoid 1143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!bitmap) continue; 1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const UvMapper mapper( 117a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy x / width, (x + bitmap->width()) / width, 118a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy y / height, (y + bitmap->height()) / height); 119a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 120a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy Texture* texture = new DelegateTexture(mTexture); 121a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this); 122a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 123a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->id = mTexture->id; 124a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->blend = !bitmap->isOpaque(); 125a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->width = bitmap->width(); 126a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->height = bitmap->height(); 127a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->uvMapper = &entry->uvMapper; 1283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mEntries.add(entry->bitmap, entry); 1303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; // namespace uirenderer 1343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; // namespace android 135