blob: 6afff1b7158eea8dbf6dffab15e75b74b2514396 [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"
Romain Guy8aa195d2013-06-04 18:00:09 -070018#include "Caches.h"
Tom Hudson2dc236b2014-10-15 15:46:42 -040019#include "Image.h"
Romain Guy3b748a42013-04-17 18:54:38 -070020
21#include <GLES2/gl2ext.h>
22
Romain Guy3b748a42013-04-17 18:54:38 -070023namespace android {
24namespace uirenderer {
25
26///////////////////////////////////////////////////////////////////////////////
27// Lifecycle
28///////////////////////////////////////////////////////////////////////////////
29
Ashok Bhat17ab38f2014-01-27 16:00:23 +000030void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) {
Romain Guy877cfe02013-05-02 17:36:28 -070031 if (mImage) {
Romain Guy3b748a42013-04-17 18:54:38 -070032 return;
33 }
34
John Reckfbc8df02014-11-14 16:18:41 -080035 ATRACE_NAME("AssetAtlas::init");
36
Romain Guy877cfe02013-05-02 17:36:28 -070037 mImage = new Image(buffer);
Romain Guya404e162013-05-24 16:19:19 -070038 if (mImage->getTexture()) {
John Reckebd52612014-12-10 16:47:36 -080039 if (!mTexture) {
40 Caches& caches = Caches::getInstance();
41 mTexture = new Texture(caches);
John Reck38e0c322015-11-10 12:19:17 -080042 mTexture->wrap(mImage->getTexture(),
43 buffer->getWidth(), buffer->getHeight(), GL_RGBA);
John Reckebd52612014-12-10 16:47:36 -080044 createEntries(caches, map, count);
45 }
Romain Guy877cfe02013-05-02 17:36:28 -070046 } else {
Romain Guyd5207b22013-05-07 14:46:36 -070047 ALOGW("Could not create atlas image");
John Reck38e0c322015-11-10 12:19:17 -080048 terminate();
Romain Guy3b748a42013-04-17 18:54:38 -070049 }
Romain Guy3b748a42013-04-17 18:54:38 -070050}
51
52void AssetAtlas::terminate() {
John Reck38e0c322015-11-10 12:19:17 -080053 delete mImage;
54 mImage = nullptr;
55 delete mTexture;
56 mTexture = nullptr;
57 mEntries.clear();
Romain Guy3b748a42013-04-17 18:54:38 -070058}
59
60///////////////////////////////////////////////////////////////////////////////
61// Entries
62///////////////////////////////////////////////////////////////////////////////
63
Chris Craik15c3f192015-12-03 12:16:56 -080064AssetAtlas::Entry* AssetAtlas::getEntry(const SkPixelRef* pixelRef) const {
John Reck38e0c322015-11-10 12:19:17 -080065 auto result = mEntries.find(pixelRef);
66 return result != mEntries.end() ? result->second.get() : nullptr;
Romain Guy3b748a42013-04-17 18:54:38 -070067}
68
Chris Craik15c3f192015-12-03 12:16:56 -080069Texture* AssetAtlas::getEntryTexture(const SkPixelRef* pixelRef) const {
John Reck38e0c322015-11-10 12:19:17 -080070 auto result = mEntries.find(pixelRef);
71 return result != mEntries.end() ? result->second->texture : nullptr;
Romain Guy3b748a42013-04-17 18:54:38 -070072}
73
74/**
Romain Guya404e162013-05-24 16:19:19 -070075 * Delegates changes to wrapping and filtering to the base atlas texture
76 * instead of applying the changes to the virtual textures.
77 */
78struct DelegateTexture: public Texture {
John Reck38e0c322015-11-10 12:19:17 -080079 DelegateTexture(Caches& caches, Texture* delegate)
80 : Texture(caches), mDelegate(delegate) { }
Romain Guya404e162013-05-24 16:19:19 -070081
82 virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
Chris Craikd41c4d82015-01-05 15:51:13 -080083 bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override {
Romain Guya404e162013-05-24 16:19:19 -070084 mDelegate->setWrapST(wrapS, wrapT, bindTexture, force, renderTarget);
85 }
86
87 virtual void setFilterMinMag(GLenum min, GLenum mag, bool bindTexture = false,
Chris Craikd41c4d82015-01-05 15:51:13 -080088 bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override {
Romain Guya404e162013-05-24 16:19:19 -070089 mDelegate->setFilterMinMag(min, mag, bindTexture, force, renderTarget);
90 }
Romain Guy7f6d6b02013-08-06 13:49:28 -070091
Romain Guya404e162013-05-24 16:19:19 -070092private:
93 Texture* const mDelegate;
94}; // struct DelegateTexture
95
Ashok Bhat17ab38f2014-01-27 16:00:23 +000096void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
John Reck38e0c322015-11-10 12:19:17 -080097 const float width = float(mTexture->width());
98 const float height = float(mTexture->height());
Romain Guya404e162013-05-24 16:19:19 -070099
Romain Guy3b748a42013-04-17 18:54:38 -0700100 for (int i = 0; i < count; ) {
John Reckc6e2e8f2015-04-15 13:24:47 -0700101 SkPixelRef* pixelRef = reinterpret_cast<SkPixelRef*>(map[i++]);
Ashok Bhat17ab38f2014-01-27 16:00:23 +0000102 // 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++]);
Romain Guy3b748a42013-04-17 18:54:38 -0700109
110 // Bitmaps should never be null, we're just extra paranoid
John Reckc6e2e8f2015-04-15 13:24:47 -0700111 if (!pixelRef) continue;
Romain Guy3b748a42013-04-17 18:54:38 -0700112
113 const UvMapper mapper(
John Reckc6e2e8f2015-04-15 13:24:47 -0700114 x / width, (x + pixelRef->info().width()) / width,
115 y / height, (y + pixelRef->info().height()) / height);
Romain Guy3b748a42013-04-17 18:54:38 -0700116
Romain Guy8aa195d2013-06-04 18:00:09 -0700117 Texture* texture = new DelegateTexture(caches, mTexture);
John Reckc6e2e8f2015-04-15 13:24:47 -0700118 texture->blend = !SkAlphaTypeIsOpaque(pixelRef->info().alphaType());
John Reck38e0c322015-11-10 12:19:17 -0800119 texture->wrap(mTexture->id(), pixelRef->info().width(),
120 pixelRef->info().height(), mTexture->format());
Romain Guy7f6d6b02013-08-06 13:49:28 -0700121
John Reck38e0c322015-11-10 12:19:17 -0800122 std::unique_ptr<Entry> entry(new Entry(pixelRef, texture, mapper, *this));
Romain Guya404e162013-05-24 16:19:19 -0700123 texture->uvMapper = &entry->uvMapper;
Romain Guy3b748a42013-04-17 18:54:38 -0700124
John Reck38e0c322015-11-10 12:19:17 -0800125 mEntries.emplace(entry->pixelRef, std::move(entry));
Romain Guy3b748a42013-04-17 18:54:38 -0700126 }
127}
128
129}; // namespace uirenderer
130}; // namespace android