Home | History | Annotate | Download | only in hwui
      1 /*
      2  * Copyright (C) 2010 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 #pragma once
     18 
     19 #include <GLES2/gl2.h>
     20 
     21 #include <utils/LruCache.h>
     22 
     23 #include <androidfw/ResourceTypes.h>
     24 
     25 #include "Debug.h"
     26 #include "utils/Pair.h"
     27 
     28 namespace android {
     29 namespace uirenderer {
     30 
     31 class Patch;
     32 
     33 ///////////////////////////////////////////////////////////////////////////////
     34 // Defines
     35 ///////////////////////////////////////////////////////////////////////////////
     36 
     37 // Debug
     38 #if DEBUG_PATCHES
     39 #define PATCH_LOGD(...) ALOGD(__VA_ARGS__)
     40 #else
     41 #define PATCH_LOGD(...)
     42 #endif
     43 
     44 ///////////////////////////////////////////////////////////////////////////////
     45 // Cache
     46 ///////////////////////////////////////////////////////////////////////////////
     47 
     48 class Caches;
     49 class RenderState;
     50 
     51 class PatchCache {
     52 public:
     53     explicit PatchCache(RenderState& renderState);
     54     ~PatchCache();
     55 
     56     const Patch* get(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
     57                      const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch);
     58     void clear();
     59 
     60     uint32_t getSize() const { return mSize; }
     61 
     62     uint32_t getMaxSize() const { return mMaxSize; }
     63 
     64     GLuint getMeshBuffer() const { return mMeshBuffer; }
     65 
     66     /**
     67      * Removes the entries associated with the specified 9-patch. This is meant
     68      * to be called from threads that are not the EGL context thread (GC thread
     69      * on the VM side for instance.)
     70      */
     71     void removeDeferred(Res_png_9patch* patch);
     72 
     73     /**
     74      * Process deferred removals.
     75      */
     76     void clearGarbage();
     77 
     78 private:
     79     struct PatchDescription {
     80         PatchDescription()
     81                 : mPatch(nullptr)
     82                 , mBitmapWidth(0)
     83                 , mBitmapHeight(0)
     84                 , mPixelWidth(0)
     85                 , mPixelHeight(0) {}
     86 
     87         PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
     88                          const float pixelWidth, const float pixelHeight,
     89                          const Res_png_9patch* patch)
     90                 : mPatch(patch)
     91                 , mBitmapWidth(bitmapWidth)
     92                 , mBitmapHeight(bitmapHeight)
     93                 , mPixelWidth(pixelWidth)
     94                 , mPixelHeight(pixelHeight) {}
     95 
     96         hash_t hash() const;
     97 
     98         const Res_png_9patch* getPatch() const { return mPatch; }
     99 
    100         static int compare(const PatchDescription& lhs, const PatchDescription& rhs);
    101 
    102         bool operator==(const PatchDescription& other) const { return compare(*this, other) == 0; }
    103 
    104         bool operator!=(const PatchDescription& other) const { return compare(*this, other) != 0; }
    105 
    106         friend inline int strictly_order_type(const PatchDescription& lhs,
    107                                               const PatchDescription& rhs) {
    108             return PatchDescription::compare(lhs, rhs) < 0;
    109         }
    110 
    111         friend inline int compare_type(const PatchDescription& lhs, const PatchDescription& rhs) {
    112             return PatchDescription::compare(lhs, rhs);
    113         }
    114 
    115         friend inline hash_t hash_type(const PatchDescription& entry) { return entry.hash(); }
    116 
    117     private:
    118         const Res_png_9patch* mPatch;
    119         uint32_t mBitmapWidth;
    120         uint32_t mBitmapHeight;
    121         float mPixelWidth;
    122         float mPixelHeight;
    123 
    124     };  // struct PatchDescription
    125 
    126     /**
    127      * A buffer block represents an empty range in the mesh buffer
    128      * that can be used to store vertices.
    129      *
    130      * The patch cache maintains a linked-list of buffer blocks
    131      * to track available regions of memory in the VBO.
    132      */
    133     struct BufferBlock {
    134         BufferBlock(uint32_t offset, uint32_t size) : offset(offset), size(size), next(nullptr) {}
    135 
    136         uint32_t offset;
    137         uint32_t size;
    138 
    139         BufferBlock* next;
    140     };  // struct BufferBlock
    141 
    142     typedef Pair<const PatchDescription*, Patch*> patch_pair_t;
    143 
    144     void clearCache();
    145     void createVertexBuffer();
    146 
    147     void setupMesh(Patch* newMesh);
    148 
    149     void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch);
    150 
    151 #if DEBUG_PATCHES
    152     void dumpFreeBlocks(const char* prefix);
    153 #endif
    154 
    155     RenderState& mRenderState;
    156     const uint32_t mMaxSize;
    157     uint32_t mSize;
    158 
    159     LruCache<PatchDescription, Patch*> mCache;
    160 
    161     GLuint mMeshBuffer;
    162     // First available free block inside the mesh buffer
    163     BufferBlock* mFreeBlocks;
    164 
    165     // Garbage tracking, required to handle GC events on the VM side
    166     Vector<Res_png_9patch*> mGarbage;
    167     mutable Mutex mLock;
    168 };  // class PatchCache
    169 
    170 };  // namespace uirenderer
    171 };  // namespace android
    172