AssetAtlas.cpp revision d41c4d8c732095ae99c955b6b82f7306633004b1
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" 212dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson#include "Image.h" 223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <GLES2/gl2ext.h> 243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android { 263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace uirenderer { 273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Lifecycle 303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 3217ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhatvoid AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) { 33877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy if (mImage) { 343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy return; 353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 37fbc8df03e498baf47ff1a5e05e182f1bcd60c770John Reck ATRACE_NAME("AssetAtlas::init"); 38fbc8df03e498baf47ff1a5e05e182f1bcd60c770John Reck 39877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy mImage = new Image(buffer); 40a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy if (mImage->getTexture()) { 41ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck if (!mTexture) { 42ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck Caches& caches = Caches::getInstance(); 43ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mTexture = new Texture(caches); 44ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mTexture->width = buffer->getWidth(); 45ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mTexture->height = buffer->getHeight(); 46ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck createEntries(caches, map, count); 47ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck } 48877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy } else { 49d5207b2eb9ba520da822d61ff78b539842fc5255Romain Guy ALOGW("Could not create atlas image"); 50877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy delete mImage; 51d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mImage = nullptr; 523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 5355b6f95ee4ace96c97508bcd14483fb4e9dbeaa0Romain Guy 54ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck updateTextureId(); 553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyvoid AssetAtlas::terminate() { 58877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy if (mImage) { 59877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy delete mImage; 60d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mImage = nullptr; 61ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck updateTextureId(); 62ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck } 63ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck} 643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 65a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 66ebd52610cfeff6e557fde284a7e1efc5e6438285John Reckvoid AssetAtlas::updateTextureId() { 67ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mTexture->id = mImage ? mImage->getTexture() : 0; 689a7fe1a034bf0a9dea7c0676211bb780d3ab30beJohn Reck if (mTexture->id) { 699a7fe1a034bf0a9dea7c0676211bb780d3ab30beJohn Reck // Texture ID changed, force-set to defaults to sync the wrapper & GL 709a7fe1a034bf0a9dea7c0676211bb780d3ab30beJohn Reck // state objects 719a7fe1a034bf0a9dea7c0676211bb780d3ab30beJohn Reck mTexture->setWrap(GL_CLAMP_TO_EDGE, false, true); 729a7fe1a034bf0a9dea7c0676211bb780d3ab30beJohn Reck mTexture->setFilter(GL_NEAREST, false, true); 739a7fe1a034bf0a9dea7c0676211bb780d3ab30beJohn Reck } 74ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck for (size_t i = 0; i < mEntries.size(); i++) { 75ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck AssetAtlas::Entry* entry = mEntries.valueAt(i); 76ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck entry->texture->id = mTexture->id; 773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy// Entries 823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/////////////////////////////////////////////////////////////////////////////// 833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 84d218a92c0afb8c0d98135b20b52ac87236e1c935Chris CraikAssetAtlas::Entry* AssetAtlas::getEntry(const SkBitmap* bitmap) const { 853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t index = mEntries.indexOfKey(bitmap); 86d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik return index >= 0 ? mEntries.valueAt(index) : nullptr; 873b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 883b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 89d218a92c0afb8c0d98135b20b52ac87236e1c935Chris CraikTexture* AssetAtlas::getEntryTexture(const SkBitmap* bitmap) const { 903b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy ssize_t index = mEntries.indexOfKey(bitmap); 91d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik return index >= 0 ? mEntries.valueAt(index)->texture : nullptr; 923b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 933b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 943b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/** 95a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy * Delegates changes to wrapping and filtering to the base atlas texture 96a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy * instead of applying the changes to the virtual textures. 97a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy */ 98a404e16e4933857464046d763ed7629cd0c86cbfRomain Guystruct DelegateTexture: public Texture { 998aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { } 100a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 101a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false, 102d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override { 103a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget); 104a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy } 105a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 106a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false, 107d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override { 108a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget); 109a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy } 1107f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy 111a404e16e4933857464046d763ed7629cd0c86cbfRomain Guyprivate: 112a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy Texture* const mDelegate; 113a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy}; // struct DelegateTexture 114a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 115a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy/** 1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * TODO: This method does not take the rotation flag into account 1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */ 11817ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhatvoid AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) { 119a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy const float width = float(mTexture->width); 120a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy const float height = float(mTexture->height); 121a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy for (int i = 0; i < count; ) { 12317ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(map[i++]); 12417ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat // NOTE: We're converting from 64 bit signed values to 32 bit 12517ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat // signed values. This is guaranteed to be safe because the "x" 12617ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat // and "y" coordinate values are guaranteed to be representable 12717ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat // with 32 bits. The array is 64 bits wide so that it can carry 12817ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat // pointers on 64 bit architectures. 12917ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat const int x = static_cast<int>(map[i++]); 13017ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat const int y = static_cast<int>(map[i++]); 1313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy bool rotated = map[i++] > 0; 1323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy // Bitmaps should never be null, we're just extra paranoid 1343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy if (!bitmap) continue; 1353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const UvMapper mapper( 137a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy x / width, (x + bitmap->width()) / width, 138a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy y / height, (y + bitmap->height()) / height); 139a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy 1408aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy Texture* texture = new DelegateTexture(caches, mTexture); 141a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->blend = !bitmap->isOpaque(); 142a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->width = bitmap->width(); 143a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->height = bitmap->height(); 1447f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy 1457f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this); 146a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy texture->uvMapper = &entry->uvMapper; 1473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy mEntries.add(entry->bitmap, entry); 1493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy } 1503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy} 1513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; // namespace uirenderer 1533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy}; // namespace android 154