Merge "Refcount RenderNode"
This commit is contained in:
@@ -59,13 +59,14 @@ static void android_view_RenderNode_output(JNIEnv* env,
|
||||
|
||||
static jlong android_view_RenderNode_create(JNIEnv* env, jobject clazz) {
|
||||
RenderNode* displayList = new RenderNode();
|
||||
displayList->incStrong(0);
|
||||
return reinterpret_cast<jlong>(displayList);
|
||||
}
|
||||
|
||||
static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
|
||||
jobject clazz, jlong displayListPtr) {
|
||||
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
||||
RenderNode::destroyDisplayListDeferred(displayList);
|
||||
displayList->decStrong(0);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@@ -315,24 +315,15 @@ void Caches::clearGarbage() {
|
||||
pathCache.clearGarbage();
|
||||
patchCache.clearGarbage();
|
||||
|
||||
Vector<RenderNode*> displayLists;
|
||||
Vector<Layer*> layers;
|
||||
|
||||
{ // scope for the lock
|
||||
Mutex::Autolock _l(mGarbageLock);
|
||||
displayLists = mDisplayListGarbage;
|
||||
layers = mLayerGarbage;
|
||||
mDisplayListGarbage.clear();
|
||||
mLayerGarbage.clear();
|
||||
}
|
||||
|
||||
size_t count = displayLists.size();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
RenderNode* displayList = displayLists.itemAt(i);
|
||||
delete displayList;
|
||||
}
|
||||
|
||||
count = layers.size();
|
||||
size_t count = layers.size();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
Layer* layer = layers.itemAt(i);
|
||||
delete layer;
|
||||
@@ -345,11 +336,6 @@ void Caches::deleteLayerDeferred(Layer* layer) {
|
||||
mLayerGarbage.push(layer);
|
||||
}
|
||||
|
||||
void Caches::deleteDisplayListDeferred(RenderNode* displayList) {
|
||||
Mutex::Autolock _l(mGarbageLock);
|
||||
mDisplayListGarbage.push(displayList);
|
||||
}
|
||||
|
||||
void Caches::flush(FlushMode mode) {
|
||||
FLUSH_LOGD("Flushing caches (mode %d)", mode);
|
||||
|
||||
|
||||
@@ -166,11 +166,6 @@ public:
|
||||
*/
|
||||
void deleteLayerDeferred(Layer* layer);
|
||||
|
||||
/*
|
||||
* Can be used to delete a display list from a non EGL thread.
|
||||
*/
|
||||
void deleteDisplayListDeferred(RenderNode* layer);
|
||||
|
||||
/**
|
||||
* Binds the VBO used to render simple textured quads.
|
||||
*/
|
||||
@@ -420,7 +415,6 @@ private:
|
||||
|
||||
mutable Mutex mGarbageLock;
|
||||
Vector<Layer*> mLayerGarbage;
|
||||
Vector<RenderNode*> mDisplayListGarbage;
|
||||
|
||||
DebugLevel mDebugLevel;
|
||||
bool mInitialized;
|
||||
|
||||
@@ -68,13 +68,13 @@ bool DeferredLayerUpdater::apply() {
|
||||
mLayer->setColorFilter(mColorFilter);
|
||||
mLayer->setAlpha(mAlpha, mMode);
|
||||
|
||||
if (mDisplayList) {
|
||||
if (mDisplayList.get()) {
|
||||
if (mWidth != mLayer->layer.getWidth() || mHeight != mLayer->layer.getHeight()) {
|
||||
success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
|
||||
}
|
||||
mLayer->setBlend(mBlend);
|
||||
mDisplayList->updateProperties();
|
||||
mLayer->updateDeferred(mDisplayList,
|
||||
mLayer->updateDeferred(mDisplayList.get(),
|
||||
mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
|
||||
mDirtyRect.setEmpty();
|
||||
mDisplayList = 0;
|
||||
|
||||
@@ -101,7 +101,7 @@ private:
|
||||
// Layer type specific properties
|
||||
// displayList and surfaceTexture are mutually exclusive, only 1 may be set
|
||||
// dirtyRect is only valid if displayList is set
|
||||
RenderNode* mDisplayList;
|
||||
sp<RenderNode> mDisplayList;
|
||||
Rect mDirtyRect;
|
||||
sp<GLConsumer> mSurfaceTexture;
|
||||
SkMatrix* mTransform;
|
||||
|
||||
@@ -29,6 +29,13 @@
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
DisplayListData::DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {
|
||||
}
|
||||
|
||||
DisplayListData::~DisplayListData() {
|
||||
cleanupResources();
|
||||
}
|
||||
|
||||
void DisplayListData::cleanupResources() {
|
||||
Caches& caches = Caches::getInstance();
|
||||
caches.unregisterFunctors(functorCount);
|
||||
@@ -91,5 +98,12 @@ void DisplayListData::cleanupResources() {
|
||||
layers.clear();
|
||||
}
|
||||
|
||||
void DisplayListData::addChild(DrawDisplayListOp* op) {
|
||||
LOG_ALWAYS_FATAL_IF(!op->renderNode(), "DrawDisplayListOp with no render node!");
|
||||
|
||||
mChildren.push(op);
|
||||
mReferenceHolders.push(op->renderNode());
|
||||
}
|
||||
|
||||
}; // namespace uirenderer
|
||||
}; // namespace android
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "Matrix.h"
|
||||
#include "DeferredDisplayList.h"
|
||||
#include "RenderProperties.h"
|
||||
#include "utils/VirtualLightRefBase.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkPaint;
|
||||
@@ -106,8 +107,8 @@ public:
|
||||
*/
|
||||
class DisplayListData {
|
||||
public:
|
||||
DisplayListData() : projectionReceiveIndex(-1), functorCount(0), hasDrawOps(false) {}
|
||||
virtual ~DisplayListData() { cleanupResources(); }
|
||||
DisplayListData();
|
||||
~DisplayListData();
|
||||
|
||||
// allocator into which all ops were allocated
|
||||
LinearAllocator allocator;
|
||||
@@ -115,9 +116,6 @@ public:
|
||||
// pointers to all ops within display list, pointing into allocator data
|
||||
Vector<DisplayListOp*> displayListOps;
|
||||
|
||||
// list of children display lists for quick, non-drawing traversal
|
||||
Vector<DrawDisplayListOp*> children;
|
||||
|
||||
// index of DisplayListOp restore, after which projected descendents should be drawn
|
||||
int projectionReceiveIndex;
|
||||
|
||||
@@ -139,7 +137,15 @@ public:
|
||||
return !displayListOps.size();
|
||||
}
|
||||
|
||||
void addChild(DrawDisplayListOp* childOp);
|
||||
const Vector<DrawDisplayListOp*>& children() { return mChildren; }
|
||||
|
||||
private:
|
||||
Vector< sp<VirtualLightRefBase> > mReferenceHolders;
|
||||
|
||||
// list of children display lists for quick, non-drawing traversal
|
||||
Vector<DrawDisplayListOp*> mChildren;
|
||||
|
||||
void cleanupResources();
|
||||
};
|
||||
|
||||
|
||||
@@ -1523,6 +1523,8 @@ public:
|
||||
|
||||
virtual const char* name() { return "DrawDisplayList"; }
|
||||
|
||||
RenderNode* renderNode() { return mDisplayList; }
|
||||
|
||||
private:
|
||||
RenderNode* mDisplayList;
|
||||
const int mFlags;
|
||||
|
||||
@@ -191,7 +191,7 @@ status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList,
|
||||
DrawDisplayListOp* op = new (alloc()) DrawDisplayListOp(displayList,
|
||||
flags, *currentTransform());
|
||||
addDrawOp(op);
|
||||
mDisplayListData->children.push(op);
|
||||
mDisplayListData->addChild(op);
|
||||
if (displayList->isProjectionReceiver()) {
|
||||
mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1;
|
||||
}
|
||||
|
||||
@@ -140,6 +140,15 @@ void Layer::removeFbo(bool flush) {
|
||||
}
|
||||
}
|
||||
|
||||
void Layer::updateDeferred(RenderNode* displayList,
|
||||
int left, int top, int right, int bottom) {
|
||||
requireRenderer();
|
||||
this->displayList = displayList;
|
||||
const Rect r(left, top, right, bottom);
|
||||
dirtyRect.unionWith(r);
|
||||
deferredUpdateScheduled = true;
|
||||
}
|
||||
|
||||
void Layer::setPaint(const SkPaint* paint) {
|
||||
OpenGLRenderer::getAlphaAndModeDirect(paint, &alpha, &mode);
|
||||
setColorFilter((paint) ? paint->getColorFilter() : NULL);
|
||||
@@ -244,7 +253,7 @@ void Layer::render() {
|
||||
renderer->prepareDirty(dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom,
|
||||
!isBlend());
|
||||
|
||||
renderer->drawDisplayList(displayList, dirtyRect, RenderNode::kReplayFlag_ClipChildren);
|
||||
renderer->drawDisplayList(displayList.get(), dirtyRect, RenderNode::kReplayFlag_ClipChildren);
|
||||
|
||||
renderer->finish();
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
#include <sys/types.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
@@ -85,13 +86,7 @@ public:
|
||||
}
|
||||
|
||||
void updateDeferred(RenderNode* displayList,
|
||||
int left, int top, int right, int bottom) {
|
||||
requireRenderer();
|
||||
this->displayList = displayList;
|
||||
const Rect r(left, top, right, bottom);
|
||||
dirtyRect.unionWith(r);
|
||||
deferredUpdateScheduled = true;
|
||||
}
|
||||
int left, int top, int right, int bottom);
|
||||
|
||||
inline uint32_t getWidth() const {
|
||||
return texture.width;
|
||||
@@ -294,7 +289,7 @@ public:
|
||||
*/
|
||||
bool deferredUpdateScheduled;
|
||||
OpenGLRenderer* renderer;
|
||||
RenderNode* displayList;
|
||||
sp<RenderNode> displayList;
|
||||
Rect dirtyRect;
|
||||
bool debugDrawUpdate;
|
||||
bool hasDrawnSinceUpdate;
|
||||
|
||||
@@ -537,7 +537,7 @@ void OpenGLRenderer::countOverdraw() {
|
||||
|
||||
bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
|
||||
if (layer->deferredUpdateScheduled && layer->renderer &&
|
||||
layer->displayList && layer->displayList->isRenderable()) {
|
||||
layer->displayList.get() && layer->displayList->isRenderable()) {
|
||||
ATRACE_CALL();
|
||||
|
||||
Rect& dirty = layer->dirtyRect;
|
||||
|
||||
@@ -59,17 +59,6 @@ RenderNode::~RenderNode() {
|
||||
delete mDisplayListData;
|
||||
}
|
||||
|
||||
void RenderNode::destroyDisplayListDeferred(RenderNode* displayList) {
|
||||
if (displayList) {
|
||||
if (Caches::hasInstance()) {
|
||||
DISPLAY_LIST_LOGD("Deferring display list destruction");
|
||||
Caches::getInstance().deleteDisplayListDeferred(displayList);
|
||||
} else {
|
||||
delete displayList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderNode::setData(DisplayListData* data) {
|
||||
delete mDisplayListData;
|
||||
mDisplayListData = data;
|
||||
@@ -104,8 +93,8 @@ void RenderNode::updateProperties() {
|
||||
}
|
||||
|
||||
if (mDisplayListData) {
|
||||
for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
|
||||
RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
|
||||
for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
|
||||
RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
|
||||
childNode->updateProperties();
|
||||
}
|
||||
}
|
||||
@@ -118,8 +107,8 @@ bool RenderNode::hasFunctors() {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < mDisplayListData->children.size(); i++) {
|
||||
RenderNode* childNode = mDisplayListData->children[i]->mDisplayList;
|
||||
for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
|
||||
RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
|
||||
if (childNode->hasFunctors()) {
|
||||
return true;
|
||||
}
|
||||
@@ -248,8 +237,8 @@ void RenderNode::computeOrdering() {
|
||||
// TODO: create temporary DDLOp and call computeOrderingImpl on top DisplayList so that
|
||||
// transform properties are applied correctly to top level children
|
||||
if (mDisplayListData == NULL) return;
|
||||
for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
|
||||
DrawDisplayListOp* childOp = mDisplayListData->children[i];
|
||||
for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
|
||||
DrawDisplayListOp* childOp = mDisplayListData->children()[i];
|
||||
childOp->mDisplayList->computeOrderingImpl(childOp,
|
||||
&mProjectedNodes, &mat4::identity());
|
||||
}
|
||||
@@ -277,11 +266,11 @@ void RenderNode::computeOrderingImpl(
|
||||
opState->mSkipInOrderDraw = false;
|
||||
}
|
||||
|
||||
if (mDisplayListData->children.size() > 0) {
|
||||
if (mDisplayListData->children().size() > 0) {
|
||||
const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0;
|
||||
bool haveAppliedPropertiesToProjection = false;
|
||||
for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
|
||||
DrawDisplayListOp* childOp = mDisplayListData->children[i];
|
||||
for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
|
||||
DrawDisplayListOp* childOp = mDisplayListData->children()[i];
|
||||
RenderNode* child = childOp->mDisplayList;
|
||||
|
||||
Vector<DrawDisplayListOp*>* projectionChildren = NULL;
|
||||
@@ -375,10 +364,10 @@ void RenderNode::replayNodeInParent(ReplayStateStruct& replayStruct, const int l
|
||||
}
|
||||
|
||||
void RenderNode::buildZSortedChildList(Vector<ZDrawDisplayListOpPair>& zTranslatedNodes) {
|
||||
if (mDisplayListData == NULL || mDisplayListData->children.size() == 0) return;
|
||||
if (mDisplayListData == NULL || mDisplayListData->children().size() == 0) return;
|
||||
|
||||
for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
|
||||
DrawDisplayListOp* childOp = mDisplayListData->children[i];
|
||||
for (unsigned int i = 0; i < mDisplayListData->children().size(); i++) {
|
||||
DrawDisplayListOp* childOp = mDisplayListData->children()[i];
|
||||
RenderNode* child = childOp->mDisplayList;
|
||||
float childZ = child->properties().getTranslationZ();
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "DeferredDisplayList.h"
|
||||
#include "DisplayList.h"
|
||||
#include "RenderProperties.h"
|
||||
#include "utils/VirtualLightRefBase.h"
|
||||
|
||||
class SkBitmap;
|
||||
class SkPaint;
|
||||
@@ -76,7 +77,7 @@ class DrawDisplayListOp;
|
||||
* recorded stream of canvas operations is refreshed. The DisplayList (and its properties) stay
|
||||
* attached.
|
||||
*/
|
||||
class RenderNode {
|
||||
class RenderNode : public VirtualLightRefBase {
|
||||
public:
|
||||
ANDROID_API RenderNode();
|
||||
ANDROID_API ~RenderNode();
|
||||
@@ -86,7 +87,6 @@ public:
|
||||
kReplayFlag_ClipChildren = 0x1
|
||||
};
|
||||
|
||||
ANDROID_API static void destroyDisplayListDeferred(RenderNode* displayList);
|
||||
ANDROID_API static void outputLogBuffer(int fd);
|
||||
|
||||
ANDROID_API void setData(DisplayListData* newData);
|
||||
|
||||
@@ -30,7 +30,19 @@ namespace android {
|
||||
namespace uirenderer {
|
||||
namespace renderthread {
|
||||
|
||||
DrawFrameTask::DrawFrameTask() : mContext(0), mRenderNode(0) {
|
||||
SetDisplayListData::SetDisplayListData() : mNewData(0) {}
|
||||
|
||||
SetDisplayListData::SetDisplayListData(RenderNode* node, DisplayListData* newData)
|
||||
: mTargetNode(node), mNewData(newData) {
|
||||
}
|
||||
|
||||
SetDisplayListData::~SetDisplayListData() {}
|
||||
|
||||
void SetDisplayListData::apply() const {
|
||||
mTargetNode->setData(mNewData);
|
||||
}
|
||||
|
||||
DrawFrameTask::DrawFrameTask() : mContext(0), mTaskMode(MODE_INVALID), mRenderNode(0) {
|
||||
}
|
||||
|
||||
DrawFrameTask::~DrawFrameTask() {
|
||||
@@ -41,13 +53,15 @@ void DrawFrameTask::setContext(CanvasContext* context) {
|
||||
}
|
||||
|
||||
void DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
|
||||
SetDisplayListData setter;
|
||||
setter.targetNode = renderNode;
|
||||
setter.newData = newData;
|
||||
LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setDisplayListData with!");
|
||||
|
||||
SetDisplayListData setter(renderNode, newData);
|
||||
mDisplayListDataUpdates.push(setter);
|
||||
}
|
||||
|
||||
void DrawFrameTask::addLayer(DeferredLayerUpdater* layer) {
|
||||
LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to addLayer with!");
|
||||
|
||||
mLayers.push(layer);
|
||||
}
|
||||
|
||||
@@ -61,6 +75,8 @@ void DrawFrameTask::removeLayer(DeferredLayerUpdater* layer) {
|
||||
}
|
||||
|
||||
void DrawFrameTask::setRenderNode(RenderNode* renderNode) {
|
||||
LOG_ALWAYS_FATAL_IF(!mContext, "Lifecycle violation, there's no context to setRenderNode with!");
|
||||
|
||||
mRenderNode = renderNode;
|
||||
}
|
||||
|
||||
@@ -69,37 +85,55 @@ void DrawFrameTask::setDirty(int left, int top, int right, int bottom) {
|
||||
}
|
||||
|
||||
void DrawFrameTask::drawFrame(RenderThread* renderThread) {
|
||||
LOG_ALWAYS_FATAL_IF(!mRenderNode, "Cannot drawFrame with no render node!");
|
||||
LOG_ALWAYS_FATAL_IF(!mRenderNode.get(), "Cannot drawFrame with no render node!");
|
||||
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
|
||||
|
||||
AutoMutex _lock(mLock);
|
||||
renderThread->queue(this);
|
||||
mSignal.wait(mLock);
|
||||
postAndWait(renderThread, MODE_FULL);
|
||||
|
||||
// Reset the single-frame data
|
||||
mDirty.setEmpty();
|
||||
mRenderNode = 0;
|
||||
}
|
||||
|
||||
void DrawFrameTask::flushStateChanges(RenderThread* renderThread) {
|
||||
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
|
||||
|
||||
postAndWait(renderThread, MODE_STATE_ONLY);
|
||||
}
|
||||
|
||||
void DrawFrameTask::postAndWait(RenderThread* renderThread, TaskMode mode) {
|
||||
LOG_ALWAYS_FATAL_IF(mode == MODE_INVALID, "That's not a real mode, silly!");
|
||||
|
||||
mTaskMode = mode;
|
||||
AutoMutex _lock(mLock);
|
||||
renderThread->queue(this);
|
||||
mSignal.wait(mLock);
|
||||
}
|
||||
|
||||
void DrawFrameTask::run() {
|
||||
ATRACE_NAME("DrawFrame");
|
||||
|
||||
syncFrameState();
|
||||
|
||||
if (mTaskMode == MODE_STATE_ONLY) {
|
||||
unblockUiThread();
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab a copy of everything we need
|
||||
Rect dirtyCopy(mDirty);
|
||||
RenderNode* renderNode = mRenderNode;
|
||||
sp<RenderNode> renderNode = mRenderNode;
|
||||
CanvasContext* context = mContext;
|
||||
|
||||
// This is temporary until WebView has a solution for syncing frame state
|
||||
bool canUnblockUiThread = !requiresSynchronousDraw(renderNode);
|
||||
bool canUnblockUiThread = !requiresSynchronousDraw(renderNode.get());
|
||||
|
||||
// From this point on anything in "this" is *UNSAFE TO ACCESS*
|
||||
if (canUnblockUiThread) {
|
||||
unblockUiThread();
|
||||
}
|
||||
|
||||
drawRenderNode(context, renderNode, &dirtyCopy);
|
||||
drawRenderNode(context, renderNode.get(), &dirtyCopy);
|
||||
|
||||
if (!canUnblockUiThread) {
|
||||
unblockUiThread();
|
||||
@@ -111,12 +145,16 @@ void DrawFrameTask::syncFrameState() {
|
||||
|
||||
for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) {
|
||||
const SetDisplayListData& setter = mDisplayListDataUpdates[i];
|
||||
setter.targetNode->setData(setter.newData);
|
||||
setter.apply();
|
||||
}
|
||||
mDisplayListDataUpdates.clear();
|
||||
|
||||
mContext->processLayerUpdates(&mLayers);
|
||||
mRenderNode->updateProperties();
|
||||
|
||||
// If we don't have an mRenderNode this is a state flush only
|
||||
if (mRenderNode.get()) {
|
||||
mRenderNode->updateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawFrameTask::unblockUiThread() {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <utils/Condition.h>
|
||||
#include <utils/Mutex.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
#include "RenderTask.h"
|
||||
@@ -36,9 +37,16 @@ namespace renderthread {
|
||||
class CanvasContext;
|
||||
class RenderThread;
|
||||
|
||||
struct SetDisplayListData {
|
||||
RenderNode* targetNode;
|
||||
DisplayListData* newData;
|
||||
class SetDisplayListData {
|
||||
public:
|
||||
// This ctor exists for Vector's usage
|
||||
SetDisplayListData();
|
||||
SetDisplayListData(RenderNode* node, DisplayListData* newData);
|
||||
~SetDisplayListData();
|
||||
void apply() const;
|
||||
private:
|
||||
sp<RenderNode> mTargetNode;
|
||||
DisplayListData* mNewData;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -61,10 +69,18 @@ public:
|
||||
void setRenderNode(RenderNode* renderNode);
|
||||
void setDirty(int left, int top, int right, int bottom);
|
||||
void drawFrame(RenderThread* renderThread);
|
||||
void flushStateChanges(RenderThread* renderThread);
|
||||
|
||||
virtual void run();
|
||||
|
||||
private:
|
||||
enum TaskMode {
|
||||
MODE_INVALID,
|
||||
MODE_FULL,
|
||||
MODE_STATE_ONLY,
|
||||
};
|
||||
|
||||
void postAndWait(RenderThread* renderThread, TaskMode mode);
|
||||
void syncFrameState();
|
||||
void unblockUiThread();
|
||||
static void drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty);
|
||||
@@ -81,7 +97,8 @@ private:
|
||||
/*********************************************
|
||||
* Single frame data
|
||||
*********************************************/
|
||||
RenderNode* mRenderNode;
|
||||
TaskMode mTaskMode;
|
||||
sp<RenderNode> mRenderNode;
|
||||
Rect mDirty;
|
||||
Vector<SetDisplayListData> mDisplayListDataUpdates;
|
||||
|
||||
|
||||
@@ -75,6 +75,9 @@ CREATE_BRIDGE1(destroyContext, CanvasContext* context) {
|
||||
|
||||
void RenderProxy::destroyContext() {
|
||||
if (mContext) {
|
||||
// Flush any pending changes to ensure all garbage is destroyed
|
||||
mDrawFrameTask.flushStateChanges(&mRenderThread);
|
||||
|
||||
SETUP_TASK(destroyContext);
|
||||
args->context = mContext;
|
||||
mContext = 0;
|
||||
@@ -138,6 +141,10 @@ CREATE_BRIDGE1(destroyCanvas, CanvasContext* context) {
|
||||
}
|
||||
|
||||
void RenderProxy::destroyCanvas() {
|
||||
// If the canvas is being destroyed we won't be drawing again anytime soon
|
||||
// So flush any pending state changes to allow for resource cleanup.
|
||||
mDrawFrameTask.flushStateChanges(&mRenderThread);
|
||||
|
||||
SETUP_TASK(destroyCanvas);
|
||||
args->context = mContext;
|
||||
post(task);
|
||||
|
||||
34
libs/hwui/utils/VirtualLightRefBase.h
Normal file
34
libs/hwui/utils/VirtualLightRefBase.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
#ifndef VIRTUALLIGHTREFBASE_H
|
||||
#define VIRTUALLIGHTREFBASE_H
|
||||
|
||||
#include <utils/RefBase.h>
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
// This is a wrapper around LightRefBase that simply enforces a virtual
|
||||
// destructor to eliminate the template requirement of LightRefBase
|
||||
class VirtualLightRefBase : public LightRefBase<VirtualLightRefBase> {
|
||||
public:
|
||||
virtual ~VirtualLightRefBase() {}
|
||||
};
|
||||
|
||||
} /* namespace uirenderer */
|
||||
} /* namespace android */
|
||||
|
||||
#endif /* VIRTUALLIGHTREFBASE_H */
|
||||
Reference in New Issue
Block a user