AssetAtlas.cpp revision 3b748a44c6bd2ea05fe16839caf73dbe50bd7ae9
1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "OpenGLRenderer" 18 19#include "AssetAtlas.h" 20 21#include <GLES2/gl2ext.h> 22 23#include <utils/Log.h> 24 25namespace android { 26namespace uirenderer { 27 28/////////////////////////////////////////////////////////////////////////////// 29// Lifecycle 30/////////////////////////////////////////////////////////////////////////////// 31 32void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) { 33 if (mImage != EGL_NO_IMAGE_KHR) { 34 return; 35 } 36 37 // Create the EGLImage object that maps the GraphicBuffer 38 EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 39 EGLClientBuffer clientBuffer = (EGLClientBuffer) buffer->getNativeBuffer(); 40 EGLint attrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; 41 42 mImage = eglCreateImageKHR(display, EGL_NO_CONTEXT, 43 EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attrs); 44 45 if (mImage == EGL_NO_IMAGE_KHR) { 46 ALOGW("Error creating atlas image (%#x)", eglGetError()); 47 return; 48 } 49 50 // Create a 2D texture to sample from the EGLImage 51 glGenTextures(1, &mTexture); 52 glBindTexture(GL_TEXTURE_2D, mTexture); 53 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, mImage); 54 55 mWidth = buffer->getWidth(); 56 mHeight = buffer->getHeight(); 57 58 createEntries(map, count); 59} 60 61void AssetAtlas::terminate() { 62 if (mImage != EGL_NO_IMAGE_KHR) { 63 eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), mImage); 64 mImage = EGL_NO_IMAGE_KHR; 65 66 glDeleteTextures(1, &mTexture); 67 mTexture = 0; 68 69 for (size_t i = 0; i < mEntries.size(); i++) { 70 delete mEntries.valueAt(i); 71 } 72 mEntries.clear(); 73 74 mWidth = mHeight = 0; 75 } 76} 77 78/////////////////////////////////////////////////////////////////////////////// 79// Entries 80/////////////////////////////////////////////////////////////////////////////// 81 82AssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const { 83 ssize_t index = mEntries.indexOfKey(bitmap); 84 return index >= 0 ? mEntries.valueAt(index) : NULL; 85} 86 87Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const { 88 ssize_t index = mEntries.indexOfKey(bitmap); 89 return index >= 0 ? &mEntries.valueAt(index)->texture : NULL; 90} 91 92/** 93 * TODO: This method does not take the rotation flag into account 94 */ 95void AssetAtlas::createEntries(int* map, int count) { 96 for (int i = 0; i < count; ) { 97 SkBitmap* bitmap = (SkBitmap*) map[i++]; 98 int x = map[i++]; 99 int y = map[i++]; 100 bool rotated = map[i++] > 0; 101 102 // Bitmaps should never be null, we're just extra paranoid 103 if (!bitmap) continue; 104 105 const UvMapper mapper( 106 x / (float) mWidth, (x + bitmap->width()) / (float) mWidth, 107 y / (float) mHeight, (y + bitmap->height()) / (float) mHeight); 108 109 Entry* entry = new Entry(bitmap, x, y, rotated, mapper, *this); 110 entry->texture.id = mTexture; 111 entry->texture.blend = !bitmap->isOpaque(); 112 entry->texture.width = bitmap->width(); 113 entry->texture.height = bitmap->height(); 114 entry->texture.uvMapper = &entry->uvMapper; 115 116 mEntries.add(entry->bitmap, entry); 117 } 118} 119 120}; // namespace uirenderer 121}; // namespace android 122