blob: 9afc54de6de2c5c55f72eb4d918c482a04673316 [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
17#ifndef ANDROID_HWUI_ASSET_ATLAS_H
18#define ANDROID_HWUI_ASSET_ATLAS_H
19
20#include <GLES2/gl2.h>
21
Romain Guy3b748a42013-04-17 18:54:38 -070022#include <ui/GraphicBuffer.h>
23
24#include <utils/KeyedVector.h>
25
26#include <cutils/compiler.h>
27
28#include <SkBitmap.h>
29
Romain Guy877cfe02013-05-02 17:36:28 -070030#include "Image.h"
Romain Guy3b748a42013-04-17 18:54:38 -070031#include "Texture.h"
32#include "UvMapper.h"
33
34namespace android {
35namespace uirenderer {
36
Romain Guy8aa195d2013-06-04 18:00:09 -070037class Caches;
38
Romain Guy3b748a42013-04-17 18:54:38 -070039/**
40 * An asset atlas holds a collection of framework bitmaps in a single OpenGL
41 * texture. Each bitmap is associated with a location, defined in pixels,
42 * inside the atlas. The atlas is generated by the framework and bound as
43 * an external texture using the EGLImageKHR extension.
44 */
45class AssetAtlas {
46public:
47 /**
48 * Entry representing the position and rotation of a
49 * bitmap inside the atlas.
50 */
51 struct Entry {
52 /**
53 * The bitmap that generated this atlas entry.
54 */
55 SkBitmap* bitmap;
56
57 /**
58 * Location of the bitmap inside the atlas, in pixels.
59 */
60 int x;
61 int y;
62
63 /**
64 * If set, the bitmap is rotated 90 degrees (clockwise)
65 * inside the atlas.
66 */
67 bool rotated;
68
Romain Guya404e162013-05-24 16:19:19 -070069 /*
70 * A "virtual texture" object that represents the texture
71 * this entry belongs to. This texture should never be
72 * modified.
73 */
74 Texture* texture;
75
Romain Guy3b748a42013-04-17 18:54:38 -070076 /**
77 * Maps texture coordinates in the [0..1] range into the
78 * correct range to sample this entry from the atlas.
79 */
80 const UvMapper uvMapper;
81
82 /**
83 * Atlas this entry belongs to.
84 */
85 const AssetAtlas& atlas;
86
Romain Guy3b748a42013-04-17 18:54:38 -070087 private:
88 Entry(SkBitmap* bitmap, int x, int y, bool rotated,
Romain Guya404e162013-05-24 16:19:19 -070089 Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
90 bitmap(bitmap), x(x), y(y), rotated(rotated),
91 texture(texture), uvMapper(mapper), atlas(atlas) { }
92
93 ~Entry() {
94 delete texture;
95 }
Romain Guy3b748a42013-04-17 18:54:38 -070096
97 friend class AssetAtlas;
98 };
99
Romain Guy55b6f952013-06-27 15:27:09 -0700100 AssetAtlas(): mTexture(NULL), mImage(NULL), mGenerationId(0) { }
Romain Guy3b748a42013-04-17 18:54:38 -0700101 ~AssetAtlas() { terminate(); }
102
103 /**
104 * Initializes the atlas with the specified buffer and
105 * map. The buffer is a gralloc'd texture that will be
106 * used as an EGLImage. The map is a list of SkBitmap*
107 * and their (x, y) positions as well as their rotation
108 * flags.
109 *
110 * This method returns immediately if the atlas is already
111 * initialized. To re-initialize the atlas, you must
112 * first call terminate().
113 */
114 ANDROID_API void init(sp<GraphicBuffer> buffer, int* map, int count);
115
116 /**
117 * Destroys the atlas texture. This object can be
118 * re-initialized after calling this method.
119 *
120 * After calling this method, the width, height
121 * and texture are set to 0.
122 */
123 ANDROID_API void terminate();
124
125 /**
126 * Returns the width of this atlas in pixels.
127 * Can return 0 if the atlas is not initialized.
128 */
129 uint32_t getWidth() const {
Romain Guya404e162013-05-24 16:19:19 -0700130 return mTexture ? mTexture->width : 0;
Romain Guy3b748a42013-04-17 18:54:38 -0700131 }
132
133 /**
134 * Returns the height of this atlas in pixels.
135 * Can return 0 if the atlas is not initialized.
136 */
137 uint32_t getHeight() const {
Romain Guya404e162013-05-24 16:19:19 -0700138 return mTexture ? mTexture->height : 0;
Romain Guy3b748a42013-04-17 18:54:38 -0700139 }
140
141 /**
142 * Returns the OpenGL name of the texture backing this atlas.
143 * Can return 0 if the atlas is not initialized.
144 */
145 GLuint getTexture() const {
Romain Guya404e162013-05-24 16:19:19 -0700146 return mTexture ? mTexture->id : 0;
Romain Guy3b748a42013-04-17 18:54:38 -0700147 }
148
149 /**
150 * Returns the entry in the atlas associated with the specified
151 * bitmap. If the bitmap is not in the atlas, return NULL.
152 */
153 Entry* getEntry(SkBitmap* const bitmap) const;
154
155 /**
156 * Returns the texture for the atlas entry associated with the
157 * specified bitmap. If the bitmap is not in the atlas, return NULL.
158 */
159 Texture* getEntryTexture(SkBitmap* const bitmap) const;
160
Romain Guy55b6f952013-06-27 15:27:09 -0700161 /**
162 * Returns the current generation id of the atlas.
163 */
164 uint32_t getGenerationId() const {
165 return mGenerationId;
166 }
167
Romain Guy3b748a42013-04-17 18:54:38 -0700168private:
Romain Guy8aa195d2013-06-04 18:00:09 -0700169 void createEntries(Caches& caches, int* map, int count);
Romain Guy3b748a42013-04-17 18:54:38 -0700170
Romain Guya404e162013-05-24 16:19:19 -0700171 Texture* mTexture;
Romain Guy877cfe02013-05-02 17:36:28 -0700172 Image* mImage;
Romain Guy3b748a42013-04-17 18:54:38 -0700173
Romain Guy55b6f952013-06-27 15:27:09 -0700174 uint32_t mGenerationId;
175
Romain Guy3b748a42013-04-17 18:54:38 -0700176 KeyedVector<SkBitmap*, Entry*> mEntries;
177}; // class AssetAtlas
178
179}; // namespace uirenderer
180}; // namespace android
181
182#endif // ANDROID_HWUI_ASSET_ATLAS_H