13b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/*
23b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Copyright (C) 2013 The Android Open Source Project
33b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
43b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Licensed under the Apache License, Version 2.0 (the "License");
53b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * you may not use this file except in compliance with the License.
63b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * You may obtain a copy of the License at
73b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
83b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *      http://www.apache.org/licenses/LICENSE-2.0
93b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy *
103b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * Unless required by applicable law or agreed to in writing, software
113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * distributed under the License is distributed on an "AS IS" BASIS,
123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * See the License for the specific language governing permissions and
143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * limitations under the License.
153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */
163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#ifndef ANDROID_HWUI_ASSET_ATLAS_H
183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#define ANDROID_HWUI_ASSET_ATLAS_H
193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <GLES2/gl2.h>
213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <ui/GraphicBuffer.h>
233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <utils/KeyedVector.h>
253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <cutils/compiler.h>
273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <SkBitmap.h>
293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
30877cfe0e32a845d5a58252b8a6e1f54f95b4379cRomain Guy#include "Image.h"
313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "Texture.h"
323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include "UvMapper.h"
333b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace android {
353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guynamespace uirenderer {
363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
378aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guyclass Caches;
388aa195d7081b889f3a7b1f426cbd8556377aae5eRomain Guy
393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy/**
403b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * An asset atlas holds a collection of framework bitmaps in a single OpenGL
413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * texture. Each bitmap is associated with a location, defined in pixels,
423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * inside the atlas. The atlas is generated by the framework and bound as
433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy * an external texture using the EGLImageKHR extension.
443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy */
453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyclass AssetAtlas {
463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guypublic:
473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Entry representing the position and rotation of a
493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * bitmap inside the atlas.
503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    struct Entry {
523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        /**
533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * The bitmap that generated this atlas entry.
543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         */
553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        SkBitmap* bitmap;
563b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        /**
583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * Location of the bitmap inside the atlas, in pixels.
593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         */
603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        int x;
613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        int y;
623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        /**
643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * If set, the bitmap is rotated 90 degrees (clockwise)
653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * inside the atlas.
663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         */
673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        bool rotated;
683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
69a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        /*
70a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy         * A "virtual texture" object that represents the texture
71a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy         * this entry belongs to. This texture should never be
72a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy         * modified.
73a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy         */
74a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        Texture* texture;
75a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy
763b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        /**
773b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * Maps texture coordinates in the [0..1] range into the
783b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * correct range to sample this entry from the atlas.
793b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         */
803b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        const UvMapper uvMapper;
813b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
823b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        /**
833b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         * Atlas this entry belongs to.
843b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy         */
853b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        const AssetAtlas& atlas;
863b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
877f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy        /**
887f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy         * Unique identifier used to merge bitmaps and 9-patches stored
897f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy         * in the atlas.
907f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy         */
917f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy        const void* getMergeId() const {
927f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy            return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
937f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy        }
947f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy
953b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    private:
963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        Entry(SkBitmap* bitmap, int x, int y, bool rotated,
97a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy                Texture* texture, const UvMapper& mapper, const AssetAtlas& atlas):
98a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy                bitmap(bitmap), x(x), y(y), rotated(rotated),
997f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy                texture(texture), uvMapper(mapper), atlas(atlas) {
1007f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy        }
101a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy
102a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        ~Entry() {
103a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy            delete texture;
104a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        }
1053b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1063b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy        friend class AssetAtlas;
1073b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    };
1083b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
109ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck    AssetAtlas(): mTexture(NULL), mImage(NULL),
1107f6d6b0370df4b5a9e0f45bffc31ea6caeeb509dRomain Guy            mBlendKey(true), mOpaqueKey(false) { }
1113b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    ~AssetAtlas() { terminate(); }
1123b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1133b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1143b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Initializes the atlas with the specified buffer and
1153b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * map. The buffer is a gralloc'd texture that will be
1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * used as an EGLImage. The map is a list of SkBitmap*
1173b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * and their (x, y) positions as well as their rotation
1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * flags.
1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * This method returns immediately if the atlas is already
1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * initialized. To re-initialize the atlas, you must
1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * first call terminate().
1233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
12417ab38f8a87bc90eab11373f878f220ce3031de6Ashok Bhat    ANDROID_API void init(sp<GraphicBuffer> buffer, int64_t* map, int count);
1253b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1263b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1273b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Destroys the atlas texture. This object can be
1283b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * re-initialized after calling this method.
1293b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     *
1303b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * After calling this method, the width, height
1313b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * and texture are set to 0.
1323b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
133ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck    void terminate();
1343b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1353b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1363b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the width of this atlas in pixels.
1373b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Can return 0 if the atlas is not initialized.
1383b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1393b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    uint32_t getWidth() const {
140a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        return mTexture ? mTexture->width : 0;
1413b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1423b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1433b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1443b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the height of this atlas in pixels.
1453b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Can return 0 if the atlas is not initialized.
1463b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1473b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    uint32_t getHeight() const {
148a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        return mTexture ? mTexture->height : 0;
1493b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1513b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1523b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the OpenGL name of the texture backing this atlas.
1533b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Can return 0 if the atlas is not initialized.
1543b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
1553b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    GLuint getTexture() const {
156a404e16e4933857464046d763ed7629cd0c86cbfRomain Guy        return mTexture ? mTexture->id : 0;
1573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    }
1583b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1593b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1603b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the entry in the atlas associated with the specified
1613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * bitmap. If the bitmap is not in the atlas, return NULL.
1623b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
163d218a92c0afb8c0d98135b20b52ac87236e1c935Chris Craik    Entry* getEntry(const SkBitmap* bitmap) const;
1643b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy
1653b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy    /**
1663b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * Returns the texture for the atlas entry associated with the
1673b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     * specified bitmap. If the bitmap is not in the atlas, return NULL.
1683b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy     */
169