• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "AssetAtlas.h"
18 #include "Caches.h"
19 #include "Image.h"
20 
21 #include <GLES2/gl2ext.h>
22 
23 namespace android {
24 namespace uirenderer {
25 
26 ///////////////////////////////////////////////////////////////////////////////
27 // Lifecycle
28 ///////////////////////////////////////////////////////////////////////////////
29 
init(sp<GraphicBuffer> buffer,int64_t * map,int count)30 void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) {
31     if (mImage) {
32         return;
33     }
34 
35     ATRACE_NAME("AssetAtlas::init");
36 
37     mImage = new Image(buffer);
38     if (mImage->getTexture()) {
39         if (!mTexture) {
40             Caches& caches = Caches::getInstance();
41             mTexture = new Texture(caches);
42             mTexture->wrap(mImage->getTexture(),
43                     buffer->getWidth(), buffer->getHeight(), GL_RGBA);
44             createEntries(caches, map, count);
45         }
46     } else {
47         ALOGW("Could not create atlas image");
48         terminate();
49     }
50 }
51 
terminate()52 void AssetAtlas::terminate() {
53     delete mImage;
54     mImage = nullptr;
55     delete mTexture;
56     mTexture = nullptr;
57     mEntries.clear();
58 }
59 
60 ///////////////////////////////////////////////////////////////////////////////
61 // Entries
62 ///////////////////////////////////////////////////////////////////////////////
63 
getEntry(const SkPixelRef * pixelRef) const64 AssetAtlas::Entry* AssetAtlas::getEntry(const SkPixelRef* pixelRef) const {
65     auto result = mEntries.find(pixelRef);
66     return result != mEntries.end() ? result->second.get() : nullptr;
67 }
68 
getEntryTexture(const SkPixelRef * pixelRef) const69 Texture* AssetAtlas::getEntryTexture(const SkPixelRef* pixelRef) const {
70     auto result = mEntries.find(pixelRef);
71     return result != mEntries.end() ? result->second->texture : nullptr;
72 }
73 
74 /**
75  * Delegates changes to wrapping and filtering to the base atlas texture
76  * instead of applying the changes to the virtual textures.
77  */
78 struct DelegateTexture: public Texture {
DelegateTextureandroid::uirenderer::DelegateTexture79     DelegateTexture(Caches& caches, Texture* delegate)
80             : Texture(caches), mDelegate(delegate) { }
81 
setWrapSTandroid::uirenderer::DelegateTexture82     virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
83             bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override {
84         mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget);
85     }
86 
setFilterMinMagandroid::uirenderer::DelegateTexture87     virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
88             bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override {
89         mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
90     }
91 
92 private:
93     Texture* const mDelegate;
94 }; // struct DelegateTexture
95 
createEntries(Caches & caches,int64_t * map,int count)96 void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
97     const float width = float(mTexture->width());
98     const float height = float(mTexture->height());
99 
100     for (int i = 0; i < count; ) {
101         SkPixelRef* pixelRef = reinterpret_cast<SkPixelRef*>(map[i++]);
102         // NOTE: We're converting from 64 bit signed values to 32 bit
103         // signed values. This is guaranteed to be safe because the "x"
104         // and "y" coordinate values are guaranteed to be representable
105         // with 32 bits. The array is 64 bits wide so that it can carry
106         // pointers on 64 bit architectures.
107         const int x = static_cast<int>(map[i++]);
108         const int y = static_cast<int>(map[i++]);
109 
110         // Bitmaps should never be null, we're just extra paranoid
111         if (!pixelRef) continue;
112 
113         const UvMapper mapper(
114                 x / width, (x + pixelRef->info().width()) / width,
115                 y / height, (y + pixelRef->info().height()) / height);
116 
117         Texture* texture = new DelegateTexture(caches, mTexture);
118         texture->blend = !SkAlphaTypeIsOpaque(pixelRef->info().alphaType());
119         texture->wrap(mTexture->id(), pixelRef->info().width(),
120                 pixelRef->info().height(), mTexture->format());
121 
122         std::unique_ptr<Entry> entry(new Entry(pixelRef, texture, mapper, *this));
123         texture->uvMapper = &entry->uvMapper;
124 
125         mEntries.emplace(entry->pixelRef, std::move(entry));
126     }
127 }
128 
129 }; // namespace uirenderer
130 }; // namespace android
131