summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/hwui/DeferredLayerUpdater.cpp9
-rw-r--r--libs/hwui/DeferredLayerUpdater.h2
-rw-r--r--libs/hwui/DisplayListRenderer.cpp4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp1
-rw-r--r--libs/hwui/RenderNode.cpp69
-rw-r--r--libs/hwui/RenderNode.h26
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp82
-rw-r--r--libs/hwui/renderthread/CanvasContext.h28
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp67
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.h30
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp58
-rw-r--r--libs/hwui/renderthread/RenderProxy.h8
12 files changed, 132 insertions, 252 deletions
diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp
index ce711b6..8b23955 100644
--- a/libs/hwui/DeferredLayerUpdater.cpp
+++ b/libs/hwui/DeferredLayerUpdater.cpp
@@ -41,6 +41,7 @@ DeferredLayerUpdater::DeferredLayerUpdater(Layer* layer, OpenGLRenderer* rendere
DeferredLayerUpdater::~DeferredLayerUpdater() {
SkSafeUnref(mColorFilter);
+ setTransform(0);
if (mLayer) {
mCaches.resourceCache.decrementRefcount(mLayer);
}
@@ -62,7 +63,7 @@ void DeferredLayerUpdater::setDisplayList(RenderNode* displayList,
}
}
-bool DeferredLayerUpdater::apply() {
+bool DeferredLayerUpdater::apply(bool* hasFunctors) {
bool success = true;
// These properties are applied the same to both layer types
mLayer->setColorFilter(mColorFilter);
@@ -73,7 +74,11 @@ bool DeferredLayerUpdater::apply() {
success = LayerRenderer::resizeLayer(mLayer, mWidth, mHeight);
}
mLayer->setBlend(mBlend);
- mDisplayList->updateProperties();
+ TreeInfo info = {0};
+ mDisplayList->prepareTree(info);
+ if (info.hasFunctors) {
+ *hasFunctors = true;
+ }
mLayer->updateDeferred(mDisplayList.get(),
mDirtyRect.left, mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom);
mDirtyRect.setEmpty();
diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h
index ce08c2d..2cc9229 100644
--- a/libs/hwui/DeferredLayerUpdater.h
+++ b/libs/hwui/DeferredLayerUpdater.h
@@ -77,7 +77,7 @@ public:
ANDROID_API void setPaint(const SkPaint* paint);
- ANDROID_API bool apply();
+ ANDROID_API bool apply(bool* hasFunctors);
ANDROID_API Layer* backingLayer() {
return mLayer;
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index a84aa6b..140a07a 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -192,7 +192,9 @@ status_t DisplayListRenderer::drawDisplayList(RenderNode* displayList,
flags, *currentTransform());
addDrawOp(op);
mDisplayListData->addChild(op);
- if (displayList->isProjectionReceiver()) {
+
+ if (displayList->stagingProperties().isProjectionReceiver()) {
+ // use staging property, since recording on UI thread
mDisplayListData->projectionReceiveIndex = mDisplayListData->displayListOps.size() - 1;
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 9dbcd36..f37487f 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1901,7 +1901,6 @@ status_t OpenGLRenderer::drawDisplayList(RenderNode* displayList, Rect& dirty,
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
// compute 3d ordering
- displayList->updateProperties();
displayList->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
status = startFrame();
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 5010076..823ae7b 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -49,7 +49,12 @@ void RenderNode::outputLogBuffer(int fd) {
fflush(file);
}
-RenderNode::RenderNode() : mDestroyed(false), mNeedsPropertiesSync(false), mDisplayListData(0) {
+RenderNode::RenderNode()
+ : mDestroyed(false)
+ , mNeedsPropertiesSync(false)
+ , mNeedsDisplayListDataSync(false)
+ , mDisplayListData(0)
+ , mStagingDisplayListData(0) {
}
RenderNode::~RenderNode() {
@@ -57,13 +62,15 @@ RenderNode::~RenderNode() {
mDestroyed = true;
delete mDisplayListData;
+ delete mStagingDisplayListData;
}
-void RenderNode::setData(DisplayListData* data) {
- delete mDisplayListData;
- mDisplayListData = data;
- if (mDisplayListData) {
- Caches::getInstance().registerFunctors(mDisplayListData->functorCount);
+void RenderNode::setStagingDisplayList(DisplayListData* data) {
+ mNeedsDisplayListDataSync = true;
+ delete mStagingDisplayListData;
+ mStagingDisplayListData = data;
+ if (mStagingDisplayListData) {
+ Caches::getInstance().registerFunctors(mStagingDisplayListData->functorCount);
}
}
@@ -86,35 +93,45 @@ void RenderNode::output(uint32_t level) {
ALOGD("%*sDone (%p, %s)", (level - 1) * 2, "", this, mName.string());
}
-void RenderNode::updateProperties() {
+void RenderNode::prepareTree(TreeInfo& info) {
+ ATRACE_CALL();
+
+ prepareTreeImpl(info);
+}
+
+void RenderNode::prepareTreeImpl(TreeInfo& info) {
+ pushStagingChanges(info);
+ prepareSubTree(info, mDisplayListData);
+}
+
+void RenderNode::pushStagingChanges(TreeInfo& info) {
if (mNeedsPropertiesSync) {
mNeedsPropertiesSync = false;
mProperties = mStagingProperties;
}
-
- if (mDisplayListData) {
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
- childNode->updateProperties();
- }
+ if (mNeedsDisplayListDataSync) {
+ mNeedsDisplayListDataSync = false;
+ // Do a push pass on the old tree to handle freeing DisplayListData
+ // that are no longer used
+ TreeInfo oldTreeInfo = {0};
+ prepareSubTree(oldTreeInfo, mDisplayListData);
+ // TODO: The damage for the old tree should be accounted for
+ delete mDisplayListData;
+ mDisplayListData = mStagingDisplayListData;
+ mStagingDisplayListData = 0;
}
}
-bool RenderNode::hasFunctors() {
- if (!mDisplayListData) return false;
-
- if (mDisplayListData->functorCount) {
- return true;
- }
-
- for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
- RenderNode* childNode = mDisplayListData->children()[i]->mDisplayList;
- if (childNode->hasFunctors()) {
- return true;
+void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
+ if (subtree) {
+ if (!info.hasFunctors) {
+ info.hasFunctors = subtree->functorCount;
+ }
+ for (size_t i = 0; i < subtree->children().size(); i++) {
+ RenderNode* childNode = subtree->children()[i]->mDisplayList;
+ childNode->prepareTreeImpl(info);
}
}
-
- return false;
}
/*
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index fd0fabc..7853701 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -65,6 +65,11 @@ class SaveOp;
class RestoreToCountOp;
class DrawDisplayListOp;
+struct TreeInfo {
+ bool hasFunctors;
+ // TODO: Damage calculations? Flag to skip staging pushes for RT animations?
+};
+
/**
* Primary class for storing recorded canvas commands, as well as per-View/ViewGroup display properties.
*
@@ -89,7 +94,7 @@ public:
ANDROID_API static void outputLogBuffer(int fd);
- ANDROID_API void setData(DisplayListData* newData);
+ ANDROID_API void setStagingDisplayList(DisplayListData* newData);
void computeOrdering();
@@ -105,6 +110,10 @@ public:
return mDisplayListData && mDisplayListData->hasDrawOps;
}
+ const char* getName() const {
+ return mName.string();
+ }
+
void setName(const char* name) {
if (name) {
char* lastPeriod = strrchr(name, '.');
@@ -129,10 +138,6 @@ public:
return mStagingProperties;
}
- bool isProjectionReceiver() {
- return properties().isProjectionReceiver();
- }
-
int getWidth() {
return properties().getWidth();
}
@@ -141,10 +146,7 @@ public:
return properties().getHeight();
}
- ANDROID_API void updateProperties();
-
- // Returns true if this RenderNode or any of its children have functors
- bool hasFunctors();
+ ANDROID_API void prepareTree(TreeInfo& info);
private:
typedef key_value_pair_t<float, DrawDisplayListOp*> ZDrawDisplayListOpPair;
@@ -203,6 +205,10 @@ private:
const char* mText;
};
+ void prepareTreeImpl(TreeInfo& info);
+ void pushStagingChanges(TreeInfo& info);
+ void prepareSubTree(TreeInfo& info, DisplayListData* subtree);
+
String8 mName;
bool mDestroyed; // used for debugging crash, TODO: remove once invalid state crash fixed
@@ -210,7 +216,9 @@ private:
RenderProperties mProperties;
RenderProperties mStagingProperties;
+ bool mNeedsDisplayListDataSync;
DisplayListData* mDisplayListData;
+ DisplayListData* mStagingDisplayListData;
/**
* Draw time state - these properties are only set and used during rendering
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index c231f6f..3638184 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -313,14 +313,11 @@ CanvasContext::CanvasContext(bool translucent)
, mDirtyRegionsEnabled(false)
, mOpaque(!translucent)
, mCanvas(0)
- , mHaveNewSurface(false)
- , mInvokeFunctorsPending(false)
- , mInvokeFunctorsTask(this) {
+ , mHaveNewSurface(false) {
mGlobalContext = GlobalContext::get();
}
CanvasContext::~CanvasContext() {
- removeFunctorsTask();
destroyCanvas();
}
@@ -347,6 +344,7 @@ void CanvasContext::setSurface(EGLNativeWindowType window) {
if (mEglSurface != EGL_NO_SURFACE) {
mDirtyRegionsEnabled = mGlobalContext->enableDirtyRegions(mEglSurface);
+ mGlobalContext->makeCurrent(mEglSurface);
mHaveNewSurface = true;
}
}
@@ -356,14 +354,15 @@ void CanvasContext::swapBuffers() {
mHaveNewSurface = false;
}
-void CanvasContext::makeCurrent() {
+void CanvasContext::requireSurface() {
+ LOG_ALWAYS_FATAL_IF(mEglSurface == EGL_NO_SURFACE,
+ "requireSurface() called but no surface set!");
mGlobalContext->makeCurrent(mEglSurface);
}
bool CanvasContext::initialize(EGLNativeWindowType window) {
if (mCanvas) return false;
setSurface(window);
- makeCurrent();
mCanvas = new OpenGLRenderer();
mCanvas->initProperties();
return true;
@@ -371,7 +370,11 @@ bool CanvasContext::initialize(EGLNativeWindowType window) {
void CanvasContext::updateSurface(EGLNativeWindowType window) {
setSurface(window);
- makeCurrent();
+}
+
+void CanvasContext::pauseSurface(EGLNativeWindowType window) {
+ // TODO: For now we just need a fence, in the future suspend any animations
+ // and such to prevent from trying to render into this surface
}
void CanvasContext::setup(int width, int height) {
@@ -379,15 +382,13 @@ void CanvasContext::setup(int width, int height) {
mCanvas->setViewport(width, height);
}
-void CanvasContext::setDisplayListData(RenderNode* displayList, DisplayListData* newData) {
- displayList->setData(newData);
-}
-
-void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters) {
+void CanvasContext::processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters,
+ bool* hasFunctors) {
+ LOG_ALWAYS_FATAL_IF(!mCanvas, "Cannot process layer updates without a canvas!");
mGlobalContext->makeCurrent(mEglSurface);
for (size_t i = 0; i < layerUpdaters->size(); i++) {
DeferredLayerUpdater* update = layerUpdaters->itemAt(i);
- LOG_ALWAYS_FATAL_IF(!update->apply(), "Failed to update layer!");
+ LOG_ALWAYS_FATAL_IF(!update->apply(hasFunctors), "Failed to update layer!");
if (update->backingLayer()->deferredUpdateScheduled) {
mCanvas->pushLayerUpdate(update->backingLayer());
}
@@ -428,60 +429,23 @@ void CanvasContext::drawDisplayList(RenderNode* displayList, Rect* dirty) {
}
}
-void InvokeFunctorsTask::run() {
- mContext->invokeFunctors();
-}
-
-void CanvasContext::attachFunctor(Functor* functor) {
- if (!mCanvas) return;
-
- mCanvas->attachFunctor(functor);
- removeFunctorsTask();
- queueFunctorsTask(0);
-}
-
-void CanvasContext::detachFunctor(Functor* functor) {
- if (!mCanvas) return;
-
- mCanvas->detachFunctor(functor);
-}
-
void CanvasContext::invokeFunctor(Functor* functor) {
+ ATRACE_CALL();
DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
if (mGlobalContext->hasContext()) {
requireGlContext();
mode = DrawGlInfo::kModeProcess;
}
- (*functor)(mode, NULL);
-}
-
-void CanvasContext::invokeFunctors() {
- mInvokeFunctorsPending = false;
-
- if (!mCanvas) return;
-
- makeCurrent();
- Rect dirty;
- mCanvas->invokeFunctors(dirty);
-}
-
-void CanvasContext::removeFunctorsTask() {
- if (!mInvokeFunctorsPending) return;
-
- mInvokeFunctorsPending = false;
- mRenderThread.remove(&mInvokeFunctorsTask);
-}
-
-void CanvasContext::queueFunctorsTask(int delayMs) {
- if (mInvokeFunctorsPending) return;
-
- mInvokeFunctorsPending = true;
- mRenderThread.queueDelayed(&mInvokeFunctorsTask, delayMs);
+ // TODO: Remove the dummy info in the future
+ DrawGlInfo dummyInfo;
+ memset(&dummyInfo, 0, sizeof(DrawGlInfo));
+ (*functor)(mode, &dummyInfo);
}
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
requireGlContext();
- layer->apply();
+ bool hasFunctors;
+ layer->apply(&hasFunctors);
return LayerRenderer::copyLayer(layer->backingLayer(), bitmap);
}
@@ -491,12 +455,12 @@ void CanvasContext::runWithGlContext(RenderTask* task) {
}
Layer* CanvasContext::createRenderLayer(int width, int height) {
- requireGlContext();
+ requireSurface();
return LayerRenderer::createRenderLayer(width, height);
}
Layer* CanvasContext::createTextureLayer() {
- requireGlContext();
+ requireSurface();
return LayerRenderer::createTextureLayer();
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6f1c37f..dcb5957 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -43,17 +43,6 @@ class GlobalContext;
class CanvasContext;
class RenderThread;
-class InvokeFunctorsTask : public RenderTask {
-public:
- InvokeFunctorsTask(CanvasContext* context)
- : mContext(context) {}
-
- virtual void run();
-
-private:
- CanvasContext* mContext;
-};
-
// This per-renderer class manages the bridge between the global EGL context
// and the render surface.
class CanvasContext {
@@ -63,16 +52,14 @@ public:
bool initialize(EGLNativeWindowType window);
void updateSurface(EGLNativeWindowType window);
+ void pauseSurface(EGLNativeWindowType window);
void setup(int width, int height);
- void setDisplayListData(RenderNode* displayList, DisplayListData* newData);
- void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters);
+ void processLayerUpdates(const Vector<DeferredLayerUpdater*>* layerUpdaters, bool* hasFunctors);
void drawDisplayList(RenderNode* displayList, Rect* dirty);
void destroyCanvas();
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
- void attachFunctor(Functor* functor);
- void detachFunctor(Functor* functor);
void invokeFunctor(Functor* functor);
void runWithGlContext(RenderTask* task);
@@ -83,12 +70,7 @@ public:
private:
void setSurface(EGLNativeWindowType window);
void swapBuffers();
- void makeCurrent();
-
- friend class InvokeFunctorsTask;
- void invokeFunctors();
- void removeFunctorsTask();
- void queueFunctorsTask(int delayMs = FUNCTOR_PROCESS_DELAY);
+ void requireSurface();
void requireGlContext();
@@ -100,10 +82,6 @@ private:
bool mOpaque;
OpenGLRenderer* mCanvas;
bool mHaveNewSurface;
-
- bool mInvokeFunctorsPending;
- InvokeFunctorsTask mInvokeFunctorsTask;
-
};
} /* namespace renderthread */
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 7b509a2..cf6c8db 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -30,19 +30,7 @@ namespace android {
namespace uirenderer {
namespace renderthread {
-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() : mContext(0), mRenderNode(0) {
}
DrawFrameTask::~DrawFrameTask() {
@@ -52,13 +40,6 @@ void DrawFrameTask::setContext(CanvasContext* context) {
mContext = context;
}
-void DrawFrameTask::setDisplayListData(RenderNode* renderNode, DisplayListData* 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!");
@@ -88,23 +69,14 @@ void DrawFrameTask::drawFrame(RenderThread* renderThread) {
LOG_ALWAYS_FATAL_IF(!mRenderNode.get(), "Cannot drawFrame with no render node!");
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
- postAndWait(renderThread, MODE_FULL);
+ postAndWait(renderThread);
// 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;
+void DrawFrameTask::postAndWait(RenderThread* renderThread) {
AutoMutex _lock(mLock);
renderThread->queue(this);
mSignal.wait(mLock);
@@ -113,21 +85,14 @@ void DrawFrameTask::postAndWait(RenderThread* renderThread, TaskMode mode) {
void DrawFrameTask::run() {
ATRACE_NAME("DrawFrame");
- syncFrameState();
-
- if (mTaskMode == MODE_STATE_ONLY) {
- unblockUiThread();
- return;
- }
+ // canUnblockUiThread is temporary until WebView has a solution for syncing frame state
+ bool canUnblockUiThread = syncFrameState();
// Grab a copy of everything we need
Rect dirtyCopy(mDirty);
sp<RenderNode> renderNode = mRenderNode;
CanvasContext* context = mContext;
- // This is temporary until WebView has a solution for syncing frame state
- bool canUnblockUiThread = !requiresSynchronousDraw(renderNode.get());
-
// From this point on anything in "this" is *UNSAFE TO ACCESS*
if (canUnblockUiThread) {
unblockUiThread();
@@ -140,21 +105,17 @@ void DrawFrameTask::run() {
}
}
-void DrawFrameTask::syncFrameState() {
+bool DrawFrameTask::syncFrameState() {
ATRACE_CALL();
- for (size_t i = 0; i < mDisplayListDataUpdates.size(); i++) {
- const SetDisplayListData& setter = mDisplayListDataUpdates[i];
- setter.apply();
- }
- mDisplayListDataUpdates.clear();
+ bool hasFunctors = false;
+ mContext->processLayerUpdates(&mLayers, &hasFunctors);
- mContext->processLayerUpdates(&mLayers);
+ TreeInfo info = {0};
+ mRenderNode->prepareTree(info);
+ hasFunctors |= info.hasFunctors;
- // If we don't have an mRenderNode this is a state flush only
- if (mRenderNode.get()) {
- mRenderNode->updateProperties();
- }
+ return !hasFunctors;
}
void DrawFrameTask::unblockUiThread() {
@@ -172,10 +133,6 @@ void DrawFrameTask::drawRenderNode(CanvasContext* context, RenderNode* renderNod
context->drawDisplayList(renderNode, dirty);
}
-bool DrawFrameTask::requiresSynchronousDraw(RenderNode* renderNode) {
- return renderNode->hasFunctors();
-}
-
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index 4e9b244..055d4cf 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -37,18 +37,6 @@ namespace renderthread {
class CanvasContext;
class RenderThread;
-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;
-};
-
/*
* This is a special Super Task. It is re-used multiple times by RenderProxy,
* and contains state (such as layer updaters & new DisplayListDatas) that is
@@ -62,33 +50,21 @@ public:
void setContext(CanvasContext* context);
- void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
void addLayer(DeferredLayerUpdater* layer);
void removeLayer(DeferredLayerUpdater* layer);
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 postAndWait(RenderThread* renderThread);
+ bool syncFrameState();
void unblockUiThread();
static void drawRenderNode(CanvasContext* context, RenderNode* renderNode, Rect* dirty);
- // This checks to see if there are any drawGlFunctors which would require
- // a synchronous drawRenderNode()
- static bool requiresSynchronousDraw(RenderNode* renderNode);
-
Mutex mLock;
Condition mSignal;
@@ -97,10 +73,8 @@ private:
/*********************************************
* Single frame data
*********************************************/
- TaskMode mTaskMode;
sp<RenderNode> mRenderNode;
Rect mDirty;
- Vector<SetDisplayListData> mDisplayListDataUpdates;
/*********************************************
* Multi frame data
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index e817e61..b233ae9 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -75,9 +75,6 @@ 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;
@@ -92,10 +89,10 @@ CREATE_BRIDGE2(initialize, CanvasContext* context, EGLNativeWindowType window) {
return (void*) args->context->initialize(args->window);
}
-bool RenderProxy::initialize(EGLNativeWindowType window) {
+bool RenderProxy::initialize(const sp<ANativeWindow>& window) {
SETUP_TASK(initialize);
args->context = mContext;
- args->window = window;
+ args->window = window.get();
return (bool) postAndWait(task);
}
@@ -104,11 +101,23 @@ CREATE_BRIDGE2(updateSurface, CanvasContext* context, EGLNativeWindowType window
return NULL;
}
-void RenderProxy::updateSurface(EGLNativeWindowType window) {
+void RenderProxy::updateSurface(const sp<ANativeWindow>& window) {
SETUP_TASK(updateSurface);
args->context = mContext;
- args->window = window;
- post(task);
+ args->window = window.get();
+ postAndWait(task);
+}
+
+CREATE_BRIDGE2(pauseSurface, CanvasContext* context, EGLNativeWindowType window) {
+ args->context->pauseSurface(args->window);
+ return NULL;
+}
+
+void RenderProxy::pauseSurface(const sp<ANativeWindow>& window) {
+ SETUP_TASK(pauseSurface);
+ args->context = mContext;
+ args->window = window.get();
+ postAndWait(task);
}
CREATE_BRIDGE3(setup, CanvasContext* context, int width, int height) {
@@ -124,10 +133,6 @@ void RenderProxy::setup(int width, int height) {
post(task);
}
-void RenderProxy::setDisplayListData(RenderNode* renderNode, DisplayListData* newData) {
- mDrawFrameTask.setDisplayListData(renderNode, newData);
-}
-
void RenderProxy::drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom) {
mDrawFrameTask.setRenderNode(displayList);
@@ -141,45 +146,18 @@ 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);
}
-CREATE_BRIDGE2(attachFunctor, CanvasContext* context, Functor* functor) {
- args->context->attachFunctor(args->functor);
- return NULL;
-}
-
-void RenderProxy::attachFunctor(Functor* functor) {
- SETUP_TASK(attachFunctor);
- args->context = mContext;
- args->functor = functor;
- post(task);
-}
-
-CREATE_BRIDGE2(detachFunctor, CanvasContext* context, Functor* functor) {
- args->context->detachFunctor(args->functor);
- return NULL;
-}
-
-void RenderProxy::detachFunctor(Functor* functor) {
- SETUP_TASK(detachFunctor);
- args->context = mContext;
- args->functor = functor;
- post(task);
-}
-
CREATE_BRIDGE2(invokeFunctor, CanvasContext* context, Functor* functor) {
args->context->invokeFunctor(args->functor);
return NULL;
}
void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
+ ATRACE_CALL();
SETUP_TASK(invokeFunctor);
args->context = mContext;
args->functor = functor;
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index c50da79..3eb8ed8 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -59,16 +59,14 @@ public:
ANDROID_API RenderProxy(bool translucent);
ANDROID_API virtual ~RenderProxy();
- ANDROID_API bool initialize(EGLNativeWindowType window);
- ANDROID_API void updateSurface(EGLNativeWindowType window);
+ ANDROID_API bool initialize(const sp<ANativeWindow>& window);
+ ANDROID_API void updateSurface(const sp<ANativeWindow>& window);
+ ANDROID_API void pauseSurface(const sp<ANativeWindow>& window);
ANDROID_API void setup(int width, int height);
- ANDROID_API void setDisplayListData(RenderNode* renderNode, DisplayListData* newData);
ANDROID_API void drawDisplayList(RenderNode* displayList,
int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
ANDROID_API void destroyCanvas();
- ANDROID_API void attachFunctor(Functor* functor);
- ANDROID_API void detachFunctor(Functor* functor);
ANDROID_API void invokeFunctor(Functor* functor, bool waitForCompletion);
ANDROID_API void runWithGlContext(RenderTask* task);