You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
4.9 KiB
180 lines
4.9 KiB
/* |
|
* Copyright (C) 2010 The Android Open Source Project |
|
* |
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
* you may not use this file except in compliance with the License. |
|
* You may obtain a copy of the License at |
|
* |
|
* http://www.apache.org/licenses/LICENSE-2.0 |
|
* |
|
* Unless required by applicable law or agreed to in writing, software |
|
* distributed under the License is distributed on an "AS IS" BASIS, |
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
* See the License for the specific language governing permissions and |
|
* limitations under the License. |
|
*/ |
|
|
|
#pragma once |
|
|
|
#include <GLES2/gl2.h> |
|
|
|
#include <utils/LruCache.h> |
|
|
|
#include <androidfw/ResourceTypes.h> |
|
|
|
#include "Debug.h" |
|
#include "utils/Pair.h" |
|
|
|
namespace android { |
|
namespace uirenderer { |
|
|
|
class Patch; |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// Defines |
|
/////////////////////////////////////////////////////////////////////////////// |
|
|
|
// Debug |
|
#if DEBUG_PATCHES |
|
#define PATCH_LOGD(...) ALOGD(__VA_ARGS__) |
|
#else |
|
#define PATCH_LOGD(...) |
|
#endif |
|
|
|
/////////////////////////////////////////////////////////////////////////////// |
|
// Cache |
|
/////////////////////////////////////////////////////////////////////////////// |
|
|
|
class Caches; |
|
class RenderState; |
|
|
|
class PatchCache { |
|
public: |
|
explicit PatchCache(RenderState& renderState); |
|
~PatchCache(); |
|
|
|
const Patch* get(const uint32_t bitmapWidth, const uint32_t bitmapHeight, |
|
const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch); |
|
void clear(); |
|
|
|
uint32_t getSize() const { |
|
return mSize; |
|
} |
|
|
|
uint32_t getMaxSize() const { |
|
return mMaxSize; |
|
} |
|
|
|
GLuint getMeshBuffer() const { |
|
return mMeshBuffer; |
|
} |
|
|
|
/** |
|
* Removes the entries associated with the specified 9-patch. This is meant |
|
* to be called from threads that are not the EGL context thread (GC thread |
|
* on the VM side for instance.) |
|
*/ |
|
void removeDeferred(Res_png_9patch* patch); |
|
|
|
/** |
|
* Process deferred removals. |
|
*/ |
|
void clearGarbage(); |
|
|
|
|
|
private: |
|
struct PatchDescription { |
|
PatchDescription(): mPatch(nullptr), mBitmapWidth(0), mBitmapHeight(0), |
|
mPixelWidth(0), mPixelHeight(0) { |
|
} |
|
|
|
PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight, |
|
const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch): |
|
mPatch(patch), mBitmapWidth(bitmapWidth), mBitmapHeight(bitmapHeight), |
|
mPixelWidth(pixelWidth), mPixelHeight(pixelHeight) { |
|
} |
|
|
|
hash_t hash() const; |
|
|
|
const Res_png_9patch* getPatch() const { return mPatch; } |
|
|
|
static int compare(const PatchDescription& lhs, const PatchDescription& rhs); |
|
|
|
bool operator==(const PatchDescription& other) const { |
|
return compare(*this, other) == 0; |
|
} |
|
|
|
bool operator!=(const PatchDescription& other) const { |
|
return compare(*this, other) != 0; |
|
} |
|
|
|
friend inline int strictly_order_type(const PatchDescription& lhs, |
|
const PatchDescription& rhs) { |
|
return PatchDescription::compare(lhs, rhs) < 0; |
|
} |
|
|
|
friend inline int compare_type(const PatchDescription& lhs, |
|
const PatchDescription& rhs) { |
|
return PatchDescription::compare(lhs, rhs); |
|
} |
|
|
|
friend inline hash_t hash_type(const PatchDescription& entry) { |
|
return entry.hash(); |
|
} |
|
|
|
private: |
|
const Res_png_9patch* mPatch; |
|
uint32_t mBitmapWidth; |
|
uint32_t mBitmapHeight; |
|
float mPixelWidth; |
|
float mPixelHeight; |
|
|
|
}; // struct PatchDescription |
|
|
|
/** |
|
* A buffer block represents an empty range in the mesh buffer |
|
* that can be used to store vertices. |
|
* |
|
* The patch cache maintains a linked-list of buffer blocks |
|
* to track available regions of memory in the VBO. |
|
*/ |
|
struct BufferBlock { |
|
BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(nullptr) { |
|
} |
|
|
|
uint32_t offset; |
|
uint32_t size; |
|
|
|
BufferBlock* next; |
|
}; // struct BufferBlock |
|
|
|
typedef Pair<const PatchDescription*, Patch*> patch_pair_t; |
|
|
|
void clearCache(); |
|
void createVertexBuffer(); |
|
|
|
void setupMesh(Patch* newMesh); |
|
|
|
void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch); |
|
|
|
#if DEBUG_PATCHES |
|
void dumpFreeBlocks(const char* prefix); |
|
#endif |
|
|
|
RenderState& mRenderState; |
|
const uint32_t mMaxSize; |
|
uint32_t mSize; |
|
|
|
LruCache<PatchDescription, Patch*> mCache; |
|
|
|
GLuint mMeshBuffer; |
|
// First available free block inside the mesh buffer |
|
BufferBlock* mFreeBlocks; |
|
|
|
// Garbage tracking, required to handle GC events on the VM side |
|
Vector<Res_png_9patch*> mGarbage; |
|
mutable Mutex mLock; |
|
}; // class PatchCache |
|
|
|
}; // namespace uirenderer |
|
}; // namespace android
|
|
|