Home | History | Annotate | Download | only in hwui
      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 
     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 
     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 
     64 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 
     69 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 {
     79     DelegateTexture(Caches& caches, Texture* delegate)
     80             : Texture(caches), mDelegate(delegate) { }
     81 
     82     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 
     87     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 
     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