blob: 17c5281cb3deb9ae7a34a329b6decd816fbc2047 [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
30#include "Texture.h"
31#include "UvMapper.h"
32
33namespace android {
34namespace uirenderer {
35
Romain Guy8aa195d2013-06-04 18:00:09 -070036class Caches;
Tom Hudson2dc236b2014-10-15 15:46:42 -040037class Image;
Romain Guy8aa195d2013-06-04 18:00:09 -070038
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 */
John Reck87ffb632015-04-15 13:24:47 -070051 class Entry {
52 public:
Romain Guya404e162013-05-24 16:19:19 -070053 /*
54 * A "virtual texture" object that represents the texture
55 * this entry belongs to. This texture should never be
56 * modified.
57 */
58 Texture* texture;
59
Romain Guy3b748a42013-04-17 18:54:38 -070060 /**
61 * Maps texture coordinates in the [0..1] range into the
62 * correct range to sample this entry from the atlas.
63 */
64 const UvMapper uvMapper;
65
66 /**
Romain Guy7f6d6b02013-08-06 13:49:28 -070067 * Unique identifier used to merge bitmaps and 9-patches stored
68 * in the atlas.
69 */
70 const void* getMergeId() const {
71 return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
72 }
73
Romain Guy3b748a42013-04-17 18:54:38 -070074 private:
John Reck87ffb632015-04-15 13:24:47 -070075 /**
76 * The pixel ref that generated this atlas entry.
77 */
78 SkPixelRef* pixelRef;
79
80 /**
81 * Location of the bitmap inside the atlas, in pixels.
82 */
83 int x;
84 int y;
85
86 /**
87 * If set, the bitmap is rotated 90 degrees (clockwise)
88 * inside the atlas.
89 */
90 bool rotated;
91
92 /**
93 * Atlas this entry belongs to.
94 */
95 const AssetAtlas& atlas;
96
97 Entry(SkPixelRef* pixelRef, int x, int y, bool rotated,
98 Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas)
99 : texture(texture)
100 , uvMapper(mapper)
101 , pixelRef(pixelRef)
102 , x(x)
103 , y(y)
104 , rotated(rotated)
105 , atlas(atlas) {
Romain Guy7f6d6b02013-08-06 13:49:28 -0700106 }
Romain Guya404e162013-05-24 16:19:19 -0700107
108 ~Entry() {
109 delete texture;
110 }
Romain Guy3b748a42013-04-17 18:54:38 -0700111
112 friend class AssetAtlas;
113 };
114
Chris Craike84a2082014-12-22 14:28:49 -0800115 AssetAtlas(): mTexture(nullptr), mImage(nullptr),
Romain Guy7f6d6b02013-08-06 13:49:28 -0700116 mBlendKey(true), mOpaqueKey(false) { }
Romain Guy3b748a42013-04-17 18:54:38 -0700117 ~AssetAtlas() { terminate(); }
118
119 /**
120 * Initializes the atlas with the specified buffer and
121 * map. The buffer is a gralloc'd texture that will be
122 * used as an EGLImage. The map is a list of SkBitmap*
123 * and their (x, y) positions as well as their rotation
124 * flags.
125 *
126 * This method returns immediately if the atlas is already
127 * initialized. To re-initialize the atlas, you must
128 * first call terminate().
129 */
Ashok Bhat17ab38f2014-01-27 16:00:23 +0000130 ANDROID_API void init(sp<GraphicBuffer> buffer, int64_t* map, int count);
Romain Guy3b748a42013-04-17 18:54:38 -0700131
132 /**
133 * Destroys the atlas texture. This object can be
134 * re-initialized after calling this method.
135 *
136 * After calling this method, the width, height
137 * and texture are set to 0.
138 */
John Reckebd52612014-12-10 16:47:36 -0800139 void terminate();
Romain Guy3b748a42013-04-17 18:54:38 -0700140
141 /**
142 * Returns the width of this atlas in pixels.
143 * Can return 0 if the atlas is not initialized.
144 */
145 uint32_t getWidth() const {
Romain Guya404e162013-05-24 16:19:19 -0700146 return mTexture ? mTexture->width : 0;
Romain Guy3b748a42013-04-17 18:54:38 -0700147 }
148
149 /**
150 * Returns the height of this atlas in pixels.
151 * Can return 0 if the atlas is not initialized.
152 */
153 uint32_t getHeight() const {
Romain Guya404e162013-05-24 16:19:19 -0700154 return mTexture ? mTexture->height : 0;
Romain Guy3b748a42013-04-17 18:54:38 -0700155 }
156
157 /**
158 * Returns the OpenGL name of the texture backing this atlas.
159 * Can return 0 if the atlas is not initialized.
160 */
161 GLuint getTexture() const {
Romain Guya404e162013-05-24 16:19:19 -0700162 return mTexture ? mTexture->id : 0;
Romain Guy3b748a42013-04-17 18:54:38 -0700163 }
164
165 /**
166 * Returns the entry in the atlas associated with the specified
167 * bitmap. If the bitmap is not in the atlas, return NULL.
168 */
Chris Craikd218a922014-01-02 17:13:34 -0800169 Entry* getEntry(const SkBitmap* bitmap) const;
Romain Guy3b748a42013-04-17 18:54:38 -0700170
171 /**
172 * Returns the texture for the atlas entry associated with the
173 * specified bitmap. If the bitmap is not in the atlas, return NULL.
174 */
Chris Craikd218a922014-01-02 17:13:34 -0800175 Texture* getEntryTexture(const SkBitmap* bitmap) const;
Romain Guy3b748a42013-04-17 18:54:38 -0700176
177private:
Ashok Bhat17ab38f2014-01-27 16:00:23 +0000178 void createEntries(Caches& caches, int64_t* map, int count);
John Reckebd52612014-12-10 16:47:36 -0800179 void updateTextureId();
Romain Guy3b748a42013-04-17 18:54:38 -0700180
Romain Guya404e162013-05-24 16:19:19 -0700181 Texture* mTexture;
Romain Guy877cfe02013-05-02 17:36:28 -0700182 Image* mImage;
Romain Guy3b748a42013-04-17 18:54:38 -0700183
Romain Guy7f6d6b02013-08-06 13:49:28 -0700184 const bool mBlendKey;
185 const bool mOpaqueKey;
186
John Reck87ffb632015-04-15 13:24:47 -0700187 KeyedVector<const SkPixelRef*, Entry*> mEntries;
Romain Guy3b748a42013-04-17 18:54:38 -0700188}; // class AssetAtlas
189
190}; // namespace uirenderer
191}; // namespace android
192
193#endif // ANDROID_HWUI_ASSET_ATLAS_H