blob: 8511e7c7f4c3f05bf585503096cae9680ef3198b [file] [log] [blame]
Romain Guy3b748a42013-04-17 18:54:38 -07001/*
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
Romain Guy3b748a42013-04-17 18:54:38 -070017#include "AssetAtlas.h"
18
19#include <GLES2/gl2ext.h>
20
Romain Guy3b748a42013-04-17 18:54:38 -070021namespace android {
22namespace uirenderer {
23
24///////////////////////////////////////////////////////////////////////////////
25// Lifecycle
26///////////////////////////////////////////////////////////////////////////////
27
28void AssetAtlas::init(sp<GraphicBuffer> buffer, int* map, int count) {
Romain Guy877cfe02013-05-02 17:36:28 -070029 if (mImage) {
Romain Guy3b748a42013-04-17 18:54:38 -070030 return;
31 }
32
Romain Guy877cfe02013-05-02 17:36:28 -070033 mImage = new Image(buffer);
Romain Guy3b748a42013-04-17 18:54:38 -070034
Romain Guya404e162013-05-24 16:19:19 -070035 if (mImage->getTexture()) {
36 mTexture = new Texture();
37 mTexture->id = mImage->getTexture();
38 mTexture->width = buffer->getWidth();
39 mTexture->height = buffer->getHeight();
Romain Guy3b748a42013-04-17 18:54:38 -070040
Romain Guy877cfe02013-05-02 17:36:28 -070041 createEntries(map, count);
42 } else {
Romain Guyd5207b22013-05-07 14:46:36 -070043 ALOGW("Could not create atlas image");
44
Romain Guy877cfe02013-05-02 17:36:28 -070045 delete mImage;
Romain Guyd5207b22013-05-07 14:46:36 -070046 mImage = NULL;
Romain Guya404e162013-05-24 16:19:19 -070047 mTexture = NULL;
Romain Guy3b748a42013-04-17 18:54:38 -070048 }
Romain Guy3b748a42013-04-17 18:54:38 -070049}
50
51void AssetAtlas::terminate() {
Romain Guy877cfe02013-05-02 17:36:28 -070052 if (mImage) {
53 delete mImage;
Romain Guyd5207b22013-05-07 14:46:36 -070054 mImage = NULL;
Romain Guy3b748a42013-04-17 18:54:38 -070055
Romain Guya404e162013-05-24 16:19:19 -070056 delete mTexture;
57 mTexture = NULL;
58
Romain Guy3b748a42013-04-17 18:54:38 -070059 for (size_t i = 0; i < mEntries.size(); i++) {
60 delete mEntries.valueAt(i);
61 }
62 mEntries.clear();
Romain Guy3b748a42013-04-17 18:54:38 -070063 }
64}
65
66///////////////////////////////////////////////////////////////////////////////
67// Entries
68///////////////////////////////////////////////////////////////////////////////
69
70AssetAtlas::Entry* AssetAtlas::getEntry(SkBitmap* const bitmap) const {
71 ssize_t index = mEntries.indexOfKey(bitmap);
72 return index >= 0 ? mEntries.valueAt(index) : NULL;
73}
74
75Texture* AssetAtlas::getEntryTexture(SkBitmap* const bitmap) const {
76 ssize_t index = mEntries.indexOfKey(bitmap);
Romain Guya404e162013-05-24 16:19:19 -070077 return index >= 0 ? mEntries.valueAt(index)->texture : NULL;
Romain Guy3b748a42013-04-17 18:54:38 -070078}
79
80/**
Romain Guya404e162013-05-24 16:19:19 -070081 * Delegates changes to wrapping and filtering to the base atlas texture
82 * instead of applying the changes to the virtual textures.
83 */
84struct DelegateTexture: public Texture {
85 DelegateTexture(Texture* delegate): Texture(), mDelegate(delegate) { }
86
87 virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
88 bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
89 mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget);
90 }
91
92 virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
93 bool force = false, GLenum renderTarget = GL_TEXTURE_2D) {
94 mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
95 }
96private:
97 Texture* const mDelegate;
98}; // struct DelegateTexture
99
100/**
Romain Guy3b748a42013-04-17 18:54:38 -0700101 * TODO: This method does not take the rotation flag into account
102 */
103void AssetAtlas::createEntries(int* map, int count) {
Romain Guya404e162013-05-24 16:19:19 -0700104 const float width = float(mTexture->width);
105 const float height = float(mTexture->height);
106
Romain Guy3b748a42013-04-17 18:54:38 -0700107 for (int i = 0; i < count; ) {
108 SkBitmap* bitmap = (SkBitmap*) map[i++];
109 int x = map[i++];
110 int y = map[i++];
111 bool rotated = map[i++] > 0;
112
113 // Bitmaps should never be null, we're just extra paranoid
114 if (!bitmap) continue;
115
116 const UvMapper mapper(
Romain Guya404e162013-05-24 16:19:19 -0700117 x / width, (x + bitmap->width()) / width,
118 y / height, (y + bitmap->height()) / height);
Romain Guy3b748a42013-04-17 18:54:38 -0700119
Romain Guya404e162013-05-24 16:19:19 -0700120 Texture* texture = new DelegateTexture(mTexture);
121 Entry* entry = new Entry(bitmap, x, y, rotated, texture, mapper, *this);
122
123 texture->id = mTexture->id;
124 texture->blend = !bitmap->isOpaque();
125 texture->width = bitmap->width();
126 texture->height = bitmap->height();
127 texture->uvMapper = &entry->uvMapper;
Romain Guy3b748a42013-04-17 18:54:38 -0700128
129 mEntries.add(entry->bitmap, entry);
130 }
131}
132
133}; // namespace uirenderer
134}; // namespace android