1f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/* 2f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * Copyright (C) 2010 The Android Open Source Project 3f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * 4f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * you may not use this file except in compliance with the License. 6f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * You may obtain a copy of the License at 7f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * 8f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 9f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * 10f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * Unless required by applicable law or agreed to in writing, software 11f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * See the License for the specific language governing permissions and 14f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy * limitations under the License. 15f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy */ 16f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 175e00c7ce063116c11315639f0035aca8ad73e8ccChris Craik#pragma once 18f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <GLES2/gl2.h> 202728f961614a385df1f056fc24803a9f65c90fabRomain Guy 213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <utils/LruCache.h> 223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 233b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy#include <androidfw/ResourceTypes.h> 243b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 25c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy#include "Debug.h" 26e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#include "utils/Pair.h" 27f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 28f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guynamespace android { 29f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guynamespace uirenderer { 30f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 312dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudsonclass Patch; 322dc236b2bae13b9a0ed9b3f7320502aecd7983b3Tom Hudson 33f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 34f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Defines 35f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 36f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 37f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Debug 38f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#if DEBUG_PATCHES 391bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#define PATCH_LOGD(...) ALOGD(__VA_ARGS__) 40f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#else 411bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck#define PATCH_LOGD(...) 42f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy#endif 43f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 44f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 45f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy// Cache 46f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy/////////////////////////////////////////////////////////////////////////////// 47f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 483b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guyclass Caches; 495e00c7ce063116c11315639f0035aca8ad73e8ccChris Craikclass RenderState; 503b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 512728f961614a385df1f056fc24803a9f65c90fabRomain Guyclass PatchCache { 52f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guypublic: 53faecb78a6b11c780db47bc940ca7662899ab5d5eChih-Hung Hsieh explicit PatchCache(RenderState& renderState); 54f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy ~PatchCache(); 55f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 56253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy const Patch* get(const uint32_t bitmapWidth, const uint32_t bitmapHeight, 571bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch); 58f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy void clear(); 59f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 601bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck uint32_t getSize() const { return mSize; } 61c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy 621bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck uint32_t getMaxSize() const { return mMaxSize; } 633b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 641bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck GLuint getMeshBuffer() const { return mMeshBuffer; } 65c15008e72ec00ca20a271c3006dac649fd07533bRomain Guy 66e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy /** 67e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * Removes the entries associated with the specified 9-patch. This is meant 68e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * to be called from threads that are not the EGL context thread (GC thread 69e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * on the VM side for instance.) 70e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy */ 71e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy void removeDeferred(Res_png_9patch* patch); 723b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 73e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy /** 74e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * Process deferred removals. 75e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy */ 76e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy void clearGarbage(); 77e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 78e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guyprivate: 796f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy struct PatchDescription { 801bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck PatchDescription() 811bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck : mPatch(nullptr) 821bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mBitmapWidth(0) 831bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mBitmapHeight(0) 841bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mPixelWidth(0) 851bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mPixelHeight(0) {} 866f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 8713ba0054846ce630ca31e8f26169fd9388faee02Romain Guy PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight, 881bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const float pixelWidth, const float pixelHeight, 891bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const Res_png_9patch* patch) 901bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck : mPatch(patch) 911bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mBitmapWidth(bitmapWidth) 921bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mBitmapHeight(bitmapHeight) 931bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mPixelWidth(pixelWidth) 941bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck , mPixelHeight(pixelHeight) {} 956f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 963b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy hash_t hash() const; 973b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 98e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy const Res_png_9patch* getPatch() const { return mPatch; } 99e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 10013ba0054846ce630ca31e8f26169fd9388faee02Romain Guy static int compare(const PatchDescription& lhs, const PatchDescription& rhs); 10113ba0054846ce630ca31e8f26169fd9388faee02Romain Guy 1021bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck bool operator==(const PatchDescription& other) const { return compare(*this, other) == 0; } 10313ba0054846ce630ca31e8f26169fd9388faee02Romain Guy 1041bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck bool operator!=(const PatchDescription& other) const { return compare(*this, other) != 0; } 10513ba0054846ce630ca31e8f26169fd9388faee02Romain Guy 10613ba0054846ce630ca31e8f26169fd9388faee02Romain Guy friend inline int strictly_order_type(const PatchDescription& lhs, 1071bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck const PatchDescription& rhs) { 10813ba0054846ce630ca31e8f26169fd9388faee02Romain Guy return PatchDescription::compare(lhs, rhs) < 0; 10913ba0054846ce630ca31e8f26169fd9388faee02Romain Guy } 11013ba0054846ce630ca31e8f26169fd9388faee02Romain Guy 1111bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck friend inline int compare_type(const PatchDescription& lhs, const PatchDescription& rhs) { 11213ba0054846ce630ca31e8f26169fd9388faee02Romain Guy return PatchDescription::compare(lhs, rhs); 1136f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy } 1146f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 1151bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck friend inline hash_t hash_type(const PatchDescription& entry) { return entry.hash(); } 1163b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy 1176f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy private: 1183b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy const Res_png_9patch* mPatch; 1193b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy uint32_t mBitmapWidth; 1203b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy uint32_t mBitmapHeight; 1213b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy float mPixelWidth; 1223b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy float mPixelHeight; 1236f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 1241bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck }; // struct PatchDescription 1256f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 126e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy /** 127e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * A buffer block represents an empty range in the mesh buffer 128e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * that can be used to store vertices. 129e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * 130e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * The patch cache maintains a linked-list of buffer blocks 131e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy * to track available regions of memory in the VBO. 132e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy */ 133e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy struct BufferBlock { 1341bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck BufferBlock(uint32_t offset, uint32_t size) : offset(offset), size(size), next(nullptr) {} 135e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 136e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy uint32_t offset; 137e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy uint32_t size; 138e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 139e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* next; 1401bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck }; // struct BufferBlock 141e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 142e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy typedef Pair<const PatchDescription*, Patch*> patch_pair_t; 143e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 144e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy void clearCache(); 145e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy void createVertexBuffer(); 146e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 1478820fd1d82acaefda98ae73ccf61413d5044f9f3Chris Craik void setupMesh(Patch* newMesh); 148e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 149e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch); 150e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 151e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#if DEBUG_PATCHES 152e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy void dumpFreeBlocks(const char* prefix); 153e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy#endif 154e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy 15596a5c4c7bab6718524de7253da8309143ab48befChris Craik RenderState& mRenderState; 15648a8f431fa52ae2ee25ffba9d20676f03bb710ffChris Craik const uint32_t mMaxSize; 1573b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy uint32_t mSize; 1586f72bebe92a4db7b5dc83f4ac5b5fd02e3b4e2cdRomain Guy 1594c2547fa9244e78115cde0a259291053108c3dc7Romain Guy LruCache<PatchDescription, Patch*> mCache; 1604c2547fa9244e78115cde0a259291053108c3dc7Romain Guy 1613b748a44c6bd2ea05fe16839caf73dbe50bd7ae9Romain Guy GLuint mMeshBuffer; 162e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // First available free block inside the mesh buffer 163e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy BufferBlock* mFreeBlocks; 1647d9b1b3c02eb1ffd99742ecb7b69e3ab97d2ba18Romain Guy 165e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy // Garbage tracking, required to handle GC events on the VM side 166e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy Vector<Res_png_9patch*> mGarbage; 167e3b0a0117a2ab4118f868a731b238fe8f2430276Romain Guy mutable Mutex mLock; 1681bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // class PatchCache 169f7f93556c8fcc640ab5adef79d021a80a72a645aRomain Guy 1701bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace uirenderer 1711bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck}; // namespace android 172