Merge "Layer changes" into lmp-mr1-dev
This commit is contained in:
@ -43,6 +43,7 @@
|
|||||||
#include <RenderNode.h>
|
#include <RenderNode.h>
|
||||||
#include <CanvasProperty.h>
|
#include <CanvasProperty.h>
|
||||||
#include <Paint.h>
|
#include <Paint.h>
|
||||||
|
#include <renderthread/RenderProxy.h>
|
||||||
|
|
||||||
#include "MinikinUtils.h"
|
#include "MinikinUtils.h"
|
||||||
|
|
||||||
@ -861,7 +862,7 @@ static void
|
|||||||
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
|
android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) {
|
||||||
#ifdef USE_OPENGL_RENDERER
|
#ifdef USE_OPENGL_RENDERER
|
||||||
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
|
int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor);
|
||||||
android::uirenderer::RenderNode::outputLogBuffer(fd);
|
android::uirenderer::renderthread::RenderProxy::outputLogBuffer(fd);
|
||||||
#endif // USE_OPENGL_RENDERER
|
#endif // USE_OPENGL_RENDERER
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,14 +265,27 @@ void Caches::dumpMemoryUsage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Caches::dumpMemoryUsage(String8 &log) {
|
void Caches::dumpMemoryUsage(String8 &log) {
|
||||||
|
uint32_t total = 0;
|
||||||
log.appendFormat("Current memory usage / total memory usage (bytes):\n");
|
log.appendFormat("Current memory usage / total memory usage (bytes):\n");
|
||||||
log.appendFormat(" TextureCache %8d / %8d\n",
|
log.appendFormat(" TextureCache %8d / %8d\n",
|
||||||
textureCache.getSize(), textureCache.getMaxSize());
|
textureCache.getSize(), textureCache.getMaxSize());
|
||||||
log.appendFormat(" LayerCache %8d / %8d (numLayers = %zu)\n",
|
log.appendFormat(" LayerCache %8d / %8d (numLayers = %zu)\n",
|
||||||
layerCache.getSize(), layerCache.getMaxSize(), layerCache.getCount());
|
layerCache.getSize(), layerCache.getMaxSize(), layerCache.getCount());
|
||||||
log.appendFormat(" Garbage layers %8zu\n", mLayerGarbage.size());
|
if (mRenderState) {
|
||||||
log.appendFormat(" Active layers %8zu\n",
|
int memused = 0;
|
||||||
mRenderState ? mRenderState->mActiveLayers.size() : 0);
|
for (std::set<const Layer*>::iterator it = mRenderState->mActiveLayers.begin();
|
||||||
|
it != mRenderState->mActiveLayers.end(); it++) {
|
||||||
|
const Layer* layer = *it;
|
||||||
|
log.appendFormat(" Layer size %dx%d; isTextureLayer()=%d; texid=%u fbo=%u; refs=%d\n",
|
||||||
|
layer->getWidth(), layer->getHeight(),
|
||||||
|
layer->isTextureLayer(), layer->getTexture(),
|
||||||
|
layer->getFbo(), layer->getStrongCount());
|
||||||
|
memused = layer->getWidth() * layer->getHeight() * 4;
|
||||||
|
}
|
||||||
|
log.appendFormat(" Layers total %8d (numLayers = %zu)\n",
|
||||||
|
memused, mRenderState->mActiveLayers.size());
|
||||||
|
total += memused;
|
||||||
|
}
|
||||||
log.appendFormat(" RenderBufferCache %8d / %8d\n",
|
log.appendFormat(" RenderBufferCache %8d / %8d\n",
|
||||||
renderBufferCache.getSize(), renderBufferCache.getMaxSize());
|
renderBufferCache.getSize(), renderBufferCache.getMaxSize());
|
||||||
log.appendFormat(" GradientCache %8d / %8d\n",
|
log.appendFormat(" GradientCache %8d / %8d\n",
|
||||||
@ -297,9 +310,7 @@ void Caches::dumpMemoryUsage(String8 &log) {
|
|||||||
log.appendFormat(" FboCache %8d / %8d\n",
|
log.appendFormat(" FboCache %8d / %8d\n",
|
||||||
fboCache.getSize(), fboCache.getMaxSize());
|
fboCache.getSize(), fboCache.getMaxSize());
|
||||||
|
|
||||||
uint32_t total = 0;
|
|
||||||
total += textureCache.getSize();
|
total += textureCache.getSize();
|
||||||
total += layerCache.getSize();
|
|
||||||
total += renderBufferCache.getSize();
|
total += renderBufferCache.getSize();
|
||||||
total += gradientCache.getSize();
|
total += gradientCache.getSize();
|
||||||
total += pathCache.getSize();
|
total += pathCache.getSize();
|
||||||
@ -323,27 +334,6 @@ void Caches::clearGarbage() {
|
|||||||
textureCache.clearGarbage();
|
textureCache.clearGarbage();
|
||||||
pathCache.clearGarbage();
|
pathCache.clearGarbage();
|
||||||
patchCache.clearGarbage();
|
patchCache.clearGarbage();
|
||||||
|
|
||||||
Vector<Layer*> layers;
|
|
||||||
|
|
||||||
{ // scope for the lock
|
|
||||||
Mutex::Autolock _l(mGarbageLock);
|
|
||||||
layers = mLayerGarbage;
|
|
||||||
mLayerGarbage.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t count = layers.size();
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
|
||||||
Layer* layer = layers.itemAt(i);
|
|
||||||
delete layer;
|
|
||||||
}
|
|
||||||
layers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Caches::deleteLayerDeferred(Layer* layer) {
|
|
||||||
Mutex::Autolock _l(mGarbageLock);
|
|
||||||
layer->state = Layer::kState_InGarbageList;
|
|
||||||
mLayerGarbage.push(layer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Caches::flush(FlushMode mode) {
|
void Caches::flush(FlushMode mode) {
|
||||||
|
@ -24,25 +24,6 @@
|
|||||||
namespace android {
|
namespace android {
|
||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
|
|
||||||
class DeleteLayerTask : public renderthread::RenderTask {
|
|
||||||
public:
|
|
||||||
DeleteLayerTask(renderthread::EglManager& eglManager, Layer* layer)
|
|
||||||
: mEglManager(eglManager)
|
|
||||||
, mLayer(layer)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual void run() {
|
|
||||||
mEglManager.requireGlContext();
|
|
||||||
LayerRenderer::destroyLayer(mLayer);
|
|
||||||
mLayer = 0;
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
renderthread::EglManager& mEglManager;
|
|
||||||
Layer* mLayer;
|
|
||||||
};
|
|
||||||
|
|
||||||
DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer)
|
DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, Layer* layer)
|
||||||
: mSurfaceTexture(0)
|
: mSurfaceTexture(0)
|
||||||
, mTransform(0)
|
, mTransform(0)
|
||||||
@ -62,7 +43,7 @@ DeferredLayerUpdater::DeferredLayerUpdater(renderthread::RenderThread& thread, L
|
|||||||
DeferredLayerUpdater::~DeferredLayerUpdater() {
|
DeferredLayerUpdater::~DeferredLayerUpdater() {
|
||||||
SkSafeUnref(mColorFilter);
|
SkSafeUnref(mColorFilter);
|
||||||
setTransform(0);
|
setTransform(0);
|
||||||
mRenderThread.queue(new DeleteLayerTask(mRenderThread.eglManager(), mLayer));
|
mLayer->postDecStrong();
|
||||||
mLayer = 0;
|
mLayer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +61,6 @@ void DisplayListData::cleanupResources() {
|
|||||||
caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i));
|
caches.resourceCache.decrementRefcountLocked(sourcePaths.itemAt(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < layers.size(); i++) {
|
|
||||||
caches.resourceCache.decrementRefcountLocked(layers.itemAt(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
caches.resourceCache.unlock();
|
caches.resourceCache.unlock();
|
||||||
|
|
||||||
for (size_t i = 0; i < paints.size(); i++) {
|
for (size_t i = 0; i < paints.size(); i++) {
|
||||||
@ -86,7 +82,6 @@ void DisplayListData::cleanupResources() {
|
|||||||
paints.clear();
|
paints.clear();
|
||||||
regions.clear();
|
regions.clear();
|
||||||
paths.clear();
|
paths.clear();
|
||||||
layers.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DisplayListData::addChild(DrawRenderNodeOp* op) {
|
size_t DisplayListData::addChild(DrawRenderNodeOp* op) {
|
||||||
|
@ -147,7 +147,6 @@ public:
|
|||||||
Vector<const SkPath*> paths;
|
Vector<const SkPath*> paths;
|
||||||
SortedVector<const SkPath*> sourcePaths;
|
SortedVector<const SkPath*> sourcePaths;
|
||||||
Vector<const SkRegion*> regions;
|
Vector<const SkRegion*> regions;
|
||||||
Vector<Layer*> layers;
|
|
||||||
Vector<Functor*> functors;
|
Vector<Functor*> functors;
|
||||||
|
|
||||||
const Vector<Chunk>& getChunks() const {
|
const Vector<Chunk>& getChunks() const {
|
||||||
@ -157,11 +156,7 @@ public:
|
|||||||
size_t addChild(DrawRenderNodeOp* childOp);
|
size_t addChild(DrawRenderNodeOp* childOp);
|
||||||
const Vector<DrawRenderNodeOp*>& children() { return mChildren; }
|
const Vector<DrawRenderNodeOp*>& children() { return mChildren; }
|
||||||
|
|
||||||
void refProperty(CanvasPropertyPrimitive* prop) {
|
void ref(VirtualLightRefBase* prop) {
|
||||||
mReferenceHolders.push(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void refProperty(CanvasPropertyPaint* prop) {
|
|
||||||
mReferenceHolders.push(prop);
|
mReferenceHolders.push(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ status_t DisplayListRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) {
|
status_t DisplayListRenderer::drawLayer(Layer* layer, float x, float y) {
|
||||||
layer = refLayer(layer);
|
mDisplayListData->ref(layer);
|
||||||
addDrawOp(new (alloc()) DrawLayerOp(layer, x, y));
|
addDrawOp(new (alloc()) DrawLayerOp(layer, x, y));
|
||||||
return DrawGlInfo::kStatusDone;
|
return DrawGlInfo::kStatusDone;
|
||||||
}
|
}
|
||||||
@ -280,13 +280,13 @@ status_t DisplayListRenderer::drawRoundRect(
|
|||||||
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
|
CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
|
||||||
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
|
CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
|
||||||
CanvasPropertyPaint* paint) {
|
CanvasPropertyPaint* paint) {
|
||||||
mDisplayListData->refProperty(left);
|
mDisplayListData->ref(left);
|
||||||
mDisplayListData->refProperty(top);
|
mDisplayListData->ref(top);
|
||||||
mDisplayListData->refProperty(right);
|
mDisplayListData->ref(right);
|
||||||
mDisplayListData->refProperty(bottom);
|
mDisplayListData->ref(bottom);
|
||||||
mDisplayListData->refProperty(rx);
|
mDisplayListData->ref(rx);
|
||||||
mDisplayListData->refProperty(ry);
|
mDisplayListData->ref(ry);
|
||||||
mDisplayListData->refProperty(paint);
|
mDisplayListData->ref(paint);
|
||||||
addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
|
addDrawOp(new (alloc()) DrawRoundRectPropsOp(&left->value, &top->value,
|
||||||
&right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
|
&right->value, &bottom->value, &rx->value, &ry->value, &paint->value));
|
||||||
return DrawGlInfo::kStatusDone;
|
return DrawGlInfo::kStatusDone;
|
||||||
@ -300,10 +300,10 @@ status_t DisplayListRenderer::drawCircle(float x, float y, float radius, const S
|
|||||||
|
|
||||||
status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
|
status_t DisplayListRenderer::drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
|
||||||
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
|
CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
|
||||||
mDisplayListData->refProperty(x);
|
mDisplayListData->ref(x);
|
||||||
mDisplayListData->refProperty(y);
|
mDisplayListData->ref(y);
|
||||||
mDisplayListData->refProperty(radius);
|
mDisplayListData->ref(radius);
|
||||||
mDisplayListData->refProperty(paint);
|
mDisplayListData->ref(paint);
|
||||||
addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
|
addDrawOp(new (alloc()) DrawCirclePropsOp(&x->value, &y->value,
|
||||||
&radius->value, &paint->value));
|
&radius->value, &paint->value));
|
||||||
return DrawGlInfo::kStatusDone;
|
return DrawGlInfo::kStatusDone;
|
||||||
|
@ -267,12 +267,6 @@ private:
|
|||||||
return regionCopy;
|
return regionCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Layer* refLayer(Layer* layer) {
|
|
||||||
mDisplayListData->layers.add(layer);
|
|
||||||
mCaches.resourceCache.incrementRefcount(layer);
|
|
||||||
return layer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
|
inline const SkBitmap* refBitmap(const SkBitmap* bitmap) {
|
||||||
// Note that this assumes the bitmap is immutable. There are cases this won't handle
|
// Note that this assumes the bitmap is immutable. There are cases this won't handle
|
||||||
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
|
// correctly, such as creating the bitmap from scratch, drawing with it, changing its
|
||||||
|
@ -35,6 +35,9 @@ Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth
|
|||||||
, renderState(renderState)
|
, renderState(renderState)
|
||||||
, texture(caches)
|
, texture(caches)
|
||||||
, type(layerType) {
|
, type(layerType) {
|
||||||
|
// TODO: This is a violation of Android's typical ref counting, but it
|
||||||
|
// preserves the old inc/dec ref locations. This should be changed...
|
||||||
|
incStrong(0);
|
||||||
mesh = NULL;
|
mesh = NULL;
|
||||||
meshElementCount = 0;
|
meshElementCount = 0;
|
||||||
cacheable = true;
|
cacheable = true;
|
||||||
@ -53,20 +56,14 @@ Layer::Layer(Type layerType, RenderState& renderState, const uint32_t layerWidth
|
|||||||
forceFilter = false;
|
forceFilter = false;
|
||||||
deferredList = NULL;
|
deferredList = NULL;
|
||||||
convexMask = NULL;
|
convexMask = NULL;
|
||||||
caches.resourceCache.incrementRefcount(this);
|
|
||||||
rendererLightPosDirty = true;
|
rendererLightPosDirty = true;
|
||||||
wasBuildLayered = false;
|
wasBuildLayered = false;
|
||||||
if (!isTextureLayer()) {
|
renderState.registerLayer(this);
|
||||||
// track only non-texture layer lifecycles in renderstate,
|
|
||||||
// because texture layers are destroyed via finalizer
|
|
||||||
renderState.registerLayer(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer::~Layer() {
|
Layer::~Layer() {
|
||||||
if (!isTextureLayer()) {
|
renderState.requireGLContext();
|
||||||
renderState.unregisterLayer(this);
|
renderState.unregisterLayer(this);
|
||||||
}
|
|
||||||
SkSafeUnref(colorFilter);
|
SkSafeUnref(colorFilter);
|
||||||
removeFbo();
|
removeFbo();
|
||||||
deleteTexture();
|
deleteTexture();
|
||||||
@ -292,5 +289,9 @@ void Layer::render(const OpenGLRenderer& rootRenderer) {
|
|||||||
renderNode = NULL;
|
renderNode = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Layer::postDecStrong() {
|
||||||
|
renderState.postDecStrong(this);
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace uirenderer
|
}; // namespace uirenderer
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
@ -52,7 +52,7 @@ class DeferStateStruct;
|
|||||||
/**
|
/**
|
||||||
* A layer has dimensions and is backed by an OpenGL texture or FBO.
|
* A layer has dimensions and is backed by an OpenGL texture or FBO.
|
||||||
*/
|
*/
|
||||||
class Layer {
|
class Layer : public VirtualLightRefBase {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
kType_Texture,
|
kType_Texture,
|
||||||
@ -279,6 +279,12 @@ public:
|
|||||||
void flush();
|
void flush();
|
||||||
void render(const OpenGLRenderer& rootRenderer);
|
void render(const OpenGLRenderer& rootRenderer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posts a decStrong call to the appropriate thread.
|
||||||
|
* Thread-safe.
|
||||||
|
*/
|
||||||
|
void postDecStrong();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bounds of the layer.
|
* Bounds of the layer.
|
||||||
*/
|
*/
|
||||||
|
@ -84,7 +84,7 @@ void LayerCache::deleteLayer(Layer* layer) {
|
|||||||
layer->getFbo());
|
layer->getFbo());
|
||||||
mSize -= layer->getWidth() * layer->getHeight() * 4;
|
mSize -= layer->getWidth() * layer->getHeight() * 4;
|
||||||
layer->state = Layer::kState_DeletedFromCache;
|
layer->state = Layer::kState_DeletedFromCache;
|
||||||
Caches::getInstance().resourceCache.decrementRefcount(layer);
|
layer->decStrong(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width
|
|||||||
|
|
||||||
// Creating a new layer always increment its refcount by 1, this allows
|
// Creating a new layer always increment its refcount by 1, this allows
|
||||||
// us to destroy the layer object if one was created for us
|
// us to destroy the layer object if one was created for us
|
||||||
Caches::getInstance().resourceCache.decrementRefcount(layer);
|
layer->decStrong(0);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -240,7 +240,7 @@ Layer* LayerRenderer::createRenderLayer(RenderState& renderState, uint32_t width
|
|||||||
if (glGetError() != GL_NO_ERROR) {
|
if (glGetError() != GL_NO_ERROR) {
|
||||||
ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height);
|
ALOGE("Could not allocate texture for layer (fbo=%d %dx%d)", fbo, width, height);
|
||||||
renderState.bindFramebuffer(previousFbo);
|
renderState.bindFramebuffer(previousFbo);
|
||||||
caches.resourceCache.decrementRefcount(layer);
|
layer->decStrong(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -316,7 +316,7 @@ void LayerRenderer::destroyLayer(Layer* layer) {
|
|||||||
|
|
||||||
if (!Caches::getInstance().layerCache.put(layer)) {
|
if (!Caches::getInstance().layerCache.put(layer)) {
|
||||||
LAYER_RENDERER_LOGD(" Destroyed!");
|
LAYER_RENDERER_LOGD(" Destroyed!");
|
||||||
Caches::getInstance().resourceCache.decrementRefcount(layer);
|
layer->decStrong(0);
|
||||||
} else {
|
} else {
|
||||||
LAYER_RENDERER_LOGD(" Cached!");
|
LAYER_RENDERER_LOGD(" Cached!");
|
||||||
#if DEBUG_LAYER_RENDERER
|
#if DEBUG_LAYER_RENDERER
|
||||||
@ -328,14 +328,6 @@ void LayerRenderer::destroyLayer(Layer* layer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerRenderer::destroyLayerDeferred(Layer* layer) {
|
|
||||||
if (layer) {
|
|
||||||
LAYER_RENDERER_LOGD("Deferring layer destruction, fbo = %d", layer->getFbo());
|
|
||||||
|
|
||||||
Caches::getInstance().deleteLayerDeferred(layer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LayerRenderer::flushLayer(RenderState& renderState, Layer* layer) {
|
void LayerRenderer::flushLayer(RenderState& renderState, Layer* layer) {
|
||||||
#ifdef GL_EXT_discard_framebuffer
|
#ifdef GL_EXT_discard_framebuffer
|
||||||
if (!layer) return;
|
if (!layer) return;
|
||||||
|
@ -60,7 +60,6 @@ public:
|
|||||||
static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
|
static void updateTextureLayer(Layer* layer, uint32_t width, uint32_t height,
|
||||||
bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform);
|
bool isOpaque, bool forceFilter, GLenum renderTarget, float* textureTransform);
|
||||||
static void destroyLayer(Layer* layer);
|
static void destroyLayer(Layer* layer);
|
||||||
ANDROID_API static void destroyLayerDeferred(Layer* layer);
|
|
||||||
static bool copyLayer(RenderState& renderState, Layer* layer, SkBitmap* bitmap);
|
static bool copyLayer(RenderState& renderState, Layer* layer, SkBitmap* bitmap);
|
||||||
|
|
||||||
static void flushLayer(RenderState& renderState, Layer* layer);
|
static void flushLayer(RenderState& renderState, Layer* layer);
|
||||||
|
@ -509,11 +509,8 @@ void OpenGLRenderer::updateLayers() {
|
|||||||
|
|
||||||
// Note: it is very important to update the layers in order
|
// Note: it is very important to update the layers in order
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
Layer* layer = mLayerUpdates.itemAt(i);
|
Layer* layer = mLayerUpdates.itemAt(i).get();
|
||||||
updateLayer(layer, false);
|
updateLayer(layer, false);
|
||||||
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
|
|
||||||
mCaches.resourceCache.decrementRefcount(layer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
|
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
|
||||||
@ -532,7 +529,7 @@ void OpenGLRenderer::flushLayers() {
|
|||||||
|
|
||||||
// Note: it is very important to update the layers in order
|
// Note: it is very important to update the layers in order
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
Layer* layer = mLayerUpdates.itemAt(i);
|
Layer* layer = mLayerUpdates.itemAt(i).get();
|
||||||
|
|
||||||
sprintf(layerName, "Layer #%d", i);
|
sprintf(layerName, "Layer #%d", i);
|
||||||
startMark(layerName);
|
startMark(layerName);
|
||||||
@ -542,8 +539,6 @@ void OpenGLRenderer::flushLayers() {
|
|||||||
|
|
||||||
ATRACE_END();
|
ATRACE_END();
|
||||||
endMark();
|
endMark();
|
||||||
|
|
||||||
mCaches.resourceCache.decrementRefcount(layer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mLayerUpdates.clear();
|
mLayerUpdates.clear();
|
||||||
@ -565,7 +560,6 @@ void OpenGLRenderer::pushLayerUpdate(Layer* layer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLayerUpdates.push_back(layer);
|
mLayerUpdates.push_back(layer);
|
||||||
mCaches.resourceCache.incrementRefcount(layer);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,25 +568,12 @@ void OpenGLRenderer::cancelLayerUpdate(Layer* layer) {
|
|||||||
for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
|
for (int i = mLayerUpdates.size() - 1; i >= 0; i--) {
|
||||||
if (mLayerUpdates.itemAt(i) == layer) {
|
if (mLayerUpdates.itemAt(i) == layer) {
|
||||||
mLayerUpdates.removeAt(i);
|
mLayerUpdates.removeAt(i);
|
||||||
mCaches.resourceCache.decrementRefcount(layer);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLRenderer::clearLayerUpdates() {
|
|
||||||
size_t count = mLayerUpdates.size();
|
|
||||||
if (count > 0) {
|
|
||||||
mCaches.resourceCache.lock();
|
|
||||||
for (size_t i = 0; i < count; i++) {
|
|
||||||
mCaches.resourceCache.decrementRefcountLocked(mLayerUpdates.itemAt(i));
|
|
||||||
}
|
|
||||||
mCaches.resourceCache.unlock();
|
|
||||||
mLayerUpdates.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLRenderer::flushLayerUpdates() {
|
void OpenGLRenderer::flushLayerUpdates() {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
syncState();
|
syncState();
|
||||||
@ -956,7 +937,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto
|
|||||||
layer->setConvexMask(NULL);
|
layer->setConvexMask(NULL);
|
||||||
if (!mCaches.layerCache.put(layer)) {
|
if (!mCaches.layerCache.put(layer)) {
|
||||||
LAYER_LOGD("Deleting layer");
|
LAYER_LOGD("Deleting layer");
|
||||||
Caches::getInstance().resourceCache.decrementRefcount(layer);
|
layer->decStrong(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +140,6 @@ public:
|
|||||||
|
|
||||||
void pushLayerUpdate(Layer* layer);
|
void pushLayerUpdate(Layer* layer);
|
||||||
void cancelLayerUpdate(Layer* layer);
|
void cancelLayerUpdate(Layer* layer);
|
||||||
void clearLayerUpdates();
|
|
||||||
void flushLayerUpdates();
|
void flushLayerUpdates();
|
||||||
void markLayersAsBuildLayers();
|
void markLayersAsBuildLayers();
|
||||||
|
|
||||||
@ -982,7 +981,7 @@ private:
|
|||||||
// List of rectangles to clear after saveLayer() is invoked
|
// List of rectangles to clear after saveLayer() is invoked
|
||||||
Vector<Rect*> mLayers;
|
Vector<Rect*> mLayers;
|
||||||
// List of layers to update at the beginning of a frame
|
// List of layers to update at the beginning of a frame
|
||||||
Vector<Layer*> mLayerUpdates;
|
Vector< sp<Layer> > mLayerUpdates;
|
||||||
|
|
||||||
// The following fields are used to setup drawing
|
// The following fields are used to setup drawing
|
||||||
// Used to describe the shaders to generate
|
// Used to describe the shaders to generate
|
||||||
|
@ -87,7 +87,11 @@ RenderNode::RenderNode()
|
|||||||
RenderNode::~RenderNode() {
|
RenderNode::~RenderNode() {
|
||||||
deleteDisplayListData();
|
deleteDisplayListData();
|
||||||
delete mStagingDisplayListData;
|
delete mStagingDisplayListData;
|
||||||
LayerRenderer::destroyLayerDeferred(mLayer);
|
if (mLayer) {
|
||||||
|
ALOGW("Memory Warning: Layer %p missed its detachment, held on to for far too long!", mLayer);
|
||||||
|
mLayer->postDecStrong();
|
||||||
|
mLayer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderNode::setStagingDisplayList(DisplayListData* data) {
|
void RenderNode::setStagingDisplayList(DisplayListData* data) {
|
||||||
@ -201,6 +205,7 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
|
|||||||
info.damageAccumulator->peekAtDirty(&dirty);
|
info.damageAccumulator->peekAtDirty(&dirty);
|
||||||
|
|
||||||
if (!mLayer) {
|
if (!mLayer) {
|
||||||
|
Caches::getInstance().dumpMemoryUsage();
|
||||||
if (info.errorHandler) {
|
if (info.errorHandler) {
|
||||||
std::string msg = "Unable to create layer for ";
|
std::string msg = "Unable to create layer for ";
|
||||||
msg += getName();
|
msg += getName();
|
||||||
|
@ -101,7 +101,7 @@ public:
|
|||||||
kReplayFlag_ClipChildren = 0x1
|
kReplayFlag_ClipChildren = 0x1
|
||||||
};
|
};
|
||||||
|
|
||||||
ANDROID_API static void outputLogBuffer(int fd);
|
static void outputLogBuffer(int fd);
|
||||||
void debugDumpLayers(const char* prefix);
|
void debugDumpLayers(const char* prefix);
|
||||||
|
|
||||||
ANDROID_API void setStagingDisplayList(DisplayListData* newData);
|
ANDROID_API void setStagingDisplayList(DisplayListData* newData);
|
||||||
|
@ -16,15 +16,18 @@
|
|||||||
#include "RenderState.h"
|
#include "RenderState.h"
|
||||||
|
|
||||||
#include "renderthread/CanvasContext.h"
|
#include "renderthread/CanvasContext.h"
|
||||||
|
#include "renderthread/EglManager.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
|
|
||||||
RenderState::RenderState()
|
RenderState::RenderState(renderthread::RenderThread& thread)
|
||||||
: mCaches(NULL)
|
: mRenderThread(thread)
|
||||||
|
, mCaches(NULL)
|
||||||
, mViewportWidth(0)
|
, mViewportWidth(0)
|
||||||
, mViewportHeight(0)
|
, mViewportHeight(0)
|
||||||
, mFramebuffer(0) {
|
, mFramebuffer(0) {
|
||||||
|
mThreadId = pthread_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderState::~RenderState() {
|
RenderState::~RenderState() {
|
||||||
@ -39,7 +42,6 @@ void RenderState::onGLContextCreated() {
|
|||||||
|
|
||||||
void RenderState::onGLContextDestroyed() {
|
void RenderState::onGLContextDestroyed() {
|
||||||
/*
|
/*
|
||||||
AutoMutex _lock(mLayerLock);
|
|
||||||
size_t size = mActiveLayers.size();
|
size_t size = mActiveLayers.size();
|
||||||
if (CC_UNLIKELY(size != 0)) {
|
if (CC_UNLIKELY(size != 0)) {
|
||||||
ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
|
ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d",
|
||||||
@ -146,5 +148,34 @@ void RenderState::debugOverdraw(bool enable, bool clear) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderState::requireGLContext() {
|
||||||
|
assertOnGLThread();
|
||||||
|
mRenderThread.eglManager().requireGlContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderState::assertOnGLThread() {
|
||||||
|
pthread_t curr = pthread_self();
|
||||||
|
LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DecStrongTask : public renderthread::RenderTask {
|
||||||
|
public:
|
||||||
|
DecStrongTask(VirtualLightRefBase* object) : mObject(object) {}
|
||||||
|
|
||||||
|
virtual void run() {
|
||||||
|
mObject->decStrong(0);
|
||||||
|
mObject = 0;
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VirtualLightRefBase* mObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
void RenderState::postDecStrong(VirtualLightRefBase* object) {
|
||||||
|
mRenderThread.queue(new DecStrongTask(object));
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace uirenderer */
|
} /* namespace uirenderer */
|
||||||
} /* namespace android */
|
} /* namespace android */
|
||||||
|
@ -53,16 +53,10 @@ public:
|
|||||||
void debugOverdraw(bool enable, bool clear);
|
void debugOverdraw(bool enable, bool clear);
|
||||||
|
|
||||||
void registerLayer(const Layer* layer) {
|
void registerLayer(const Layer* layer) {
|
||||||
/*
|
|
||||||
AutoMutex _lock(mLayerLock);
|
|
||||||
mActiveLayers.insert(layer);
|
mActiveLayers.insert(layer);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
void unregisterLayer(const Layer* layer) {
|
void unregisterLayer(const Layer* layer) {
|
||||||
/*
|
|
||||||
AutoMutex _lock(mLayerLock);
|
|
||||||
mActiveLayers.erase(layer);
|
mActiveLayers.erase(layer);
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerCanvasContext(renderthread::CanvasContext* context) {
|
void registerCanvasContext(renderthread::CanvasContext* context) {
|
||||||
@ -73,16 +67,24 @@ public:
|
|||||||
mRegisteredContexts.erase(context);
|
mRegisteredContexts.erase(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void requireGLContext();
|
||||||
|
|
||||||
|
// TODO: This system is a little clunky feeling, this could use some
|
||||||
|
// more thinking...
|
||||||
|
void postDecStrong(VirtualLightRefBase* object);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class renderthread::RenderThread;
|
friend class renderthread::RenderThread;
|
||||||
friend class Caches;
|
friend class Caches;
|
||||||
|
|
||||||
void interruptForFunctorInvoke();
|
void interruptForFunctorInvoke();
|
||||||
void resumeFromFunctorInvoke();
|
void resumeFromFunctorInvoke();
|
||||||
|
void assertOnGLThread();
|
||||||
|
|
||||||
RenderState();
|
RenderState(renderthread::RenderThread& thread);
|
||||||
~RenderState();
|
~RenderState();
|
||||||
|
|
||||||
|
renderthread::RenderThread& mRenderThread;
|
||||||
Caches* mCaches;
|
Caches* mCaches;
|
||||||
std::set<const Layer*> mActiveLayers;
|
std::set<const Layer*> mActiveLayers;
|
||||||
std::set<renderthread::CanvasContext*> mRegisteredContexts;
|
std::set<renderthread::CanvasContext*> mRegisteredContexts;
|
||||||
@ -90,7 +92,8 @@ private:
|
|||||||
GLsizei mViewportWidth;
|
GLsizei mViewportWidth;
|
||||||
GLsizei mViewportHeight;
|
GLsizei mViewportHeight;
|
||||||
GLuint mFramebuffer;
|
GLuint mFramebuffer;
|
||||||
Mutex mLayerLock;
|
|
||||||
|
pthread_t mThreadId;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace uirenderer */
|
} /* namespace uirenderer */
|
||||||
|
@ -75,10 +75,6 @@ void ResourceCache::incrementRefcount(const Res_png_9patch* patchResource) {
|
|||||||
incrementRefcount((void*) patchResource, kNinePatch);
|
incrementRefcount((void*) patchResource, kNinePatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::incrementRefcount(Layer* layerResource) {
|
|
||||||
incrementRefcount((void*) layerResource, kLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
|
void ResourceCache::incrementRefcountLocked(void* resource, ResourceType resourceType) {
|
||||||
ssize_t index = mCache->indexOfKey(resource);
|
ssize_t index = mCache->indexOfKey(resource);
|
||||||
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
|
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
|
||||||
@ -103,10 +99,6 @@ void ResourceCache::incrementRefcountLocked(const Res_png_9patch* patchResource)
|
|||||||
incrementRefcountLocked((void*) patchResource, kNinePatch);
|
incrementRefcountLocked((void*) patchResource, kNinePatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::incrementRefcountLocked(Layer* layerResource) {
|
|
||||||
incrementRefcountLocked((void*) layerResource, kLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceCache::decrementRefcount(void* resource) {
|
void ResourceCache::decrementRefcount(void* resource) {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
decrementRefcountLocked(resource);
|
decrementRefcountLocked(resource);
|
||||||
@ -126,10 +118,6 @@ void ResourceCache::decrementRefcount(const Res_png_9patch* patchResource) {
|
|||||||
decrementRefcount((void*) patchResource);
|
decrementRefcount((void*) patchResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::decrementRefcount(Layer* layerResource) {
|
|
||||||
decrementRefcount((void*) layerResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceCache::decrementRefcountLocked(void* resource) {
|
void ResourceCache::decrementRefcountLocked(void* resource) {
|
||||||
ssize_t index = mCache->indexOfKey(resource);
|
ssize_t index = mCache->indexOfKey(resource);
|
||||||
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
|
ResourceReference* ref = index >= 0 ? mCache->valueAt(index) : NULL;
|
||||||
@ -157,10 +145,6 @@ void ResourceCache::decrementRefcountLocked(const Res_png_9patch* patchResource)
|
|||||||
decrementRefcountLocked((void*) patchResource);
|
decrementRefcountLocked((void*) patchResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceCache::decrementRefcountLocked(Layer* layerResource) {
|
|
||||||
decrementRefcountLocked((void*) layerResource);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResourceCache::destructor(SkPath* resource) {
|
void ResourceCache::destructor(SkPath* resource) {
|
||||||
Mutex::Autolock _l(mLock);
|
Mutex::Autolock _l(mLock);
|
||||||
destructorLocked(resource);
|
destructorLocked(resource);
|
||||||
@ -274,7 +258,7 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource
|
|||||||
if (ref->recycled && ref->resourceType == kBitmap) {
|
if (ref->recycled && ref->resourceType == kBitmap) {
|
||||||
((SkBitmap*) resource)->setPixels(NULL, NULL);
|
((SkBitmap*) resource)->setPixels(NULL, NULL);
|
||||||
}
|
}
|
||||||
if (ref->destroyed || ref->resourceType == kLayer) {
|
if (ref->destroyed) {
|
||||||
switch (ref->resourceType) {
|
switch (ref->resourceType) {
|
||||||
case kBitmap: {
|
case kBitmap: {
|
||||||
SkBitmap* bitmap = (SkBitmap*) resource;
|
SkBitmap* bitmap = (SkBitmap*) resource;
|
||||||
@ -305,11 +289,6 @@ void ResourceCache::deleteResourceReferenceLocked(const void* resource, Resource
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kLayer: {
|
|
||||||
Layer* layer = (Layer*) resource;
|
|
||||||
Caches::getInstance().deleteLayerDeferred(layer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mCache->removeItem(resource);
|
mCache->removeItem(resource);
|
||||||
|
@ -36,8 +36,7 @@ namespace uirenderer {
|
|||||||
enum ResourceType {
|
enum ResourceType {
|
||||||
kBitmap,
|
kBitmap,
|
||||||
kNinePatch,
|
kNinePatch,
|
||||||
kPath,
|
kPath
|
||||||
kLayer
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class ResourceReference {
|
class ResourceReference {
|
||||||
@ -69,22 +68,18 @@ public:
|
|||||||
void incrementRefcount(const SkPath* resource);
|
void incrementRefcount(const SkPath* resource);
|
||||||
void incrementRefcount(const SkBitmap* resource);
|
void incrementRefcount(const SkBitmap* resource);
|
||||||
void incrementRefcount(const Res_png_9patch* resource);
|
void incrementRefcount(const Res_png_9patch* resource);
|
||||||
void incrementRefcount(Layer* resource);
|
|
||||||
|
|
||||||
void incrementRefcountLocked(const SkPath* resource);
|
void incrementRefcountLocked(const SkPath* resource);
|
||||||
void incrementRefcountLocked(const SkBitmap* resource);
|
void incrementRefcountLocked(const SkBitmap* resource);
|
||||||
void incrementRefcountLocked(const Res_png_9patch* resource);
|
void incrementRefcountLocked(const Res_png_9patch* resource);
|
||||||
void incrementRefcountLocked(Layer* resource);
|
|
||||||
|
|
||||||
void decrementRefcount(const SkBitmap* resource);
|
void decrementRefcount(const SkBitmap* resource);
|
||||||
void decrementRefcount(const SkPath* resource);
|
void decrementRefcount(const SkPath* resource);
|
||||||
void decrementRefcount(const Res_png_9patch* resource);
|
void decrementRefcount(const Res_png_9patch* resource);
|
||||||
void decrementRefcount(Layer* resource);
|
|
||||||
|
|
||||||
void decrementRefcountLocked(const SkBitmap* resource);
|
void decrementRefcountLocked(const SkBitmap* resource);
|
||||||
void decrementRefcountLocked(const SkPath* resource);
|
void decrementRefcountLocked(const SkPath* resource);
|
||||||
void decrementRefcountLocked(const Res_png_9patch* resource);
|
void decrementRefcountLocked(const Res_png_9patch* resource);
|
||||||
void decrementRefcountLocked(Layer* resource);
|
|
||||||
|
|
||||||
void destructor(SkPath* resource);
|
void destructor(SkPath* resource);
|
||||||
void destructor(const SkBitmap* resource);
|
void destructor(const SkBitmap* resource);
|
||||||
|
@ -236,6 +236,8 @@ void CanvasContext::draw() {
|
|||||||
|
|
||||||
if (status & DrawGlInfo::kStatusDrew) {
|
if (status & DrawGlInfo::kStatusDrew) {
|
||||||
swapBuffers();
|
swapBuffers();
|
||||||
|
} else {
|
||||||
|
mEglManager.cancelFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler().finishFrame();
|
profiler().finishFrame();
|
||||||
|
@ -73,7 +73,8 @@ EglManager::EglManager(RenderThread& thread)
|
|||||||
, mAllowPreserveBuffer(load_dirty_regions_property())
|
, mAllowPreserveBuffer(load_dirty_regions_property())
|
||||||
, mCurrentSurface(EGL_NO_SURFACE)
|
, mCurrentSurface(EGL_NO_SURFACE)
|
||||||
, mAtlasMap(NULL)
|
, mAtlasMap(NULL)
|
||||||
, mAtlasMapSize(0) {
|
, mAtlasMapSize(0)
|
||||||
|
, mInFrame(false) {
|
||||||
mCanSetPreserveBuffer = mAllowPreserveBuffer;
|
mCanSetPreserveBuffer = mAllowPreserveBuffer;
|
||||||
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
|
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
|
||||||
}
|
}
|
||||||
@ -105,10 +106,12 @@ bool EglManager::hasEglContext() {
|
|||||||
void EglManager::requireGlContext() {
|
void EglManager::requireGlContext() {
|
||||||
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
|
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
|
||||||
|
|
||||||
// We can't be certain about the state of the current surface (whether
|
if (!mInFrame) {
|
||||||
// or not it is destroyed, for example), so err on the side of using
|
// We can't be certain about the state of the current surface (whether
|
||||||
// the pbuffer surface which we fully control
|
// or not it is destroyed, for example), so err on the side of using
|
||||||
usePBufferSurface();
|
// the pbuffer surface which we fully control
|
||||||
|
usePBufferSurface();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EglManager::loadConfig() {
|
void EglManager::loadConfig() {
|
||||||
@ -251,9 +254,11 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
|
|||||||
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
|
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
|
||||||
}
|
}
|
||||||
eglBeginFrame(mEglDisplay, surface);
|
eglBeginFrame(mEglDisplay, surface);
|
||||||
|
mInFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EglManager::swapBuffers(EGLSurface surface) {
|
bool EglManager::swapBuffers(EGLSurface surface) {
|
||||||
|
mInFrame = false;
|
||||||
eglSwapBuffers(mEglDisplay, surface);
|
eglSwapBuffers(mEglDisplay, surface);
|
||||||
EGLint err = eglGetError();
|
EGLint err = eglGetError();
|
||||||
if (CC_LIKELY(err == EGL_SUCCESS)) {
|
if (CC_LIKELY(err == EGL_SUCCESS)) {
|
||||||
@ -272,6 +277,10 @@ bool EglManager::swapBuffers(EGLSurface surface) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EglManager::cancelFrame() {
|
||||||
|
mInFrame = false;
|
||||||
|
}
|
||||||
|
|
||||||
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
|
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
|
||||||
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
|
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ public:
|
|||||||
bool makeCurrent(EGLSurface surface);
|
bool makeCurrent(EGLSurface surface);
|
||||||
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
|
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
|
||||||
bool swapBuffers(EGLSurface surface);
|
bool swapBuffers(EGLSurface surface);
|
||||||
|
void cancelFrame();
|
||||||
|
|
||||||
// Returns true iff the surface is now preserving buffers.
|
// Returns true iff the surface is now preserving buffers.
|
||||||
bool setPreserveBuffer(EGLSurface surface, bool preserve);
|
bool setPreserveBuffer(EGLSurface surface, bool preserve);
|
||||||
@ -80,6 +81,12 @@ private:
|
|||||||
sp<GraphicBuffer> mAtlasBuffer;
|
sp<GraphicBuffer> mAtlasBuffer;
|
||||||
int64_t* mAtlasMap;
|
int64_t* mAtlasMap;
|
||||||
size_t mAtlasMapSize;
|
size_t mAtlasMapSize;
|
||||||
|
|
||||||
|
// Whether or not we are in the middle of drawing a frame. This is used
|
||||||
|
// to avoid switching surfaces mid-frame if requireGlContext() is called
|
||||||
|
// TODO: Need to be better about surface/context management so that this isn't
|
||||||
|
// necessary
|
||||||
|
bool mInFrame;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace renderthread */
|
} /* namespace renderthread */
|
||||||
|
@ -235,12 +235,7 @@ void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
|
|||||||
// waitForCompletion = true is expected to be fairly rare and only
|
// waitForCompletion = true is expected to be fairly rare and only
|
||||||
// happen in destruction. Thus it should be fine to temporarily
|
// happen in destruction. Thus it should be fine to temporarily
|
||||||
// create a Mutex
|
// create a Mutex
|
||||||
Mutex mutex;
|
staticPostAndWait(task);
|
||||||
Condition condition;
|
|
||||||
SignalingRenderTask syncTask(task, &mutex, &condition);
|
|
||||||
AutoMutex _lock(mutex);
|
|
||||||
thread.queue(&syncTask);
|
|
||||||
condition.wait(mutex);
|
|
||||||
} else {
|
} else {
|
||||||
thread.queue(task);
|
thread.queue(task);
|
||||||
}
|
}
|
||||||
@ -258,17 +253,6 @@ void RenderProxy::runWithGlContext(RenderTask* gltask) {
|
|||||||
postAndWait(task);
|
postAndWait(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_BRIDGE1(destroyLayer, Layer* layer) {
|
|
||||||
LayerRenderer::destroyLayer(args->layer);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderProxy::enqueueDestroyLayer(Layer* layer) {
|
|
||||||
SETUP_TASK(destroyLayer);
|
|
||||||
args->layer = layer;
|
|
||||||
RenderThread::getInstance().queue(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
|
CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
|
||||||
Layer* layer = args->context->createTextureLayer();
|
Layer* layer = args->context->createTextureLayer();
|
||||||
if (!layer) return 0;
|
if (!layer) return 0;
|
||||||
@ -400,6 +384,17 @@ void RenderProxy::dumpProfileInfo(int fd) {
|
|||||||
postAndWait(task);
|
postAndWait(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CREATE_BRIDGE1(outputLogBuffer, int fd) {
|
||||||
|
RenderNode::outputLogBuffer(args->fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderProxy::outputLogBuffer(int fd) {
|
||||||
|
SETUP_TASK(outputLogBuffer);
|
||||||
|
args->fd = fd;
|
||||||
|
staticPostAndWait(task);
|
||||||
|
}
|
||||||
|
|
||||||
CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) {
|
CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) {
|
||||||
CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
|
CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
|
||||||
args->buffer->decStrong(0);
|
args->buffer->decStrong(0);
|
||||||
@ -430,6 +425,19 @@ void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* RenderProxy::staticPostAndWait(MethodInvokeRenderTask* task) {
|
||||||
|
RenderThread& thread = RenderThread::getInstance();
|
||||||
|
void* retval;
|
||||||
|
task->setReturnPtr(&retval);
|
||||||
|
Mutex mutex;
|
||||||
|
Condition condition;
|
||||||
|
SignalingRenderTask syncTask(task, &mutex, &condition);
|
||||||
|
AutoMutex _lock(mutex);
|
||||||
|
thread.queue(&syncTask);
|
||||||
|
condition.wait(mutex);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace renderthread */
|
} /* namespace renderthread */
|
||||||
} /* namespace uirenderer */
|
} /* namespace uirenderer */
|
||||||
} /* namespace android */
|
} /* namespace android */
|
||||||
|
@ -81,7 +81,6 @@ public:
|
|||||||
|
|
||||||
ANDROID_API void runWithGlContext(RenderTask* task);
|
ANDROID_API void runWithGlContext(RenderTask* task);
|
||||||
|
|
||||||
static void enqueueDestroyLayer(Layer* layer);
|
|
||||||
ANDROID_API DeferredLayerUpdater* createTextureLayer();
|
ANDROID_API DeferredLayerUpdater* createTextureLayer();
|
||||||
ANDROID_API void buildLayer(RenderNode* node);
|
ANDROID_API void buildLayer(RenderNode* node);
|
||||||
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
|
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
|
||||||
@ -97,6 +96,7 @@ public:
|
|||||||
ANDROID_API void notifyFramePending();
|
ANDROID_API void notifyFramePending();
|
||||||
|
|
||||||
ANDROID_API void dumpProfileInfo(int fd);
|
ANDROID_API void dumpProfileInfo(int fd);
|
||||||
|
ANDROID_API static void outputLogBuffer(int fd);
|
||||||
|
|
||||||
ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);
|
ANDROID_API void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size);
|
||||||
|
|
||||||
@ -114,6 +114,8 @@ private:
|
|||||||
void post(RenderTask* task);
|
void post(RenderTask* task);
|
||||||
void* postAndWait(MethodInvokeRenderTask* task);
|
void* postAndWait(MethodInvokeRenderTask* task);
|
||||||
|
|
||||||
|
static void* staticPostAndWait(MethodInvokeRenderTask* task);
|
||||||
|
|
||||||
// Friend class to help with bridging
|
// Friend class to help with bridging
|
||||||
friend class RenderProxyBridge;
|
friend class RenderProxyBridge;
|
||||||
};
|
};
|
||||||
|
@ -168,7 +168,7 @@ void RenderThread::initializeDisplayEventReceiver() {
|
|||||||
void RenderThread::initThreadLocals() {
|
void RenderThread::initThreadLocals() {
|
||||||
initializeDisplayEventReceiver();
|
initializeDisplayEventReceiver();
|
||||||
mEglManager = new EglManager(*this);
|
mEglManager = new EglManager(*this);
|
||||||
mRenderState = new RenderState();
|
mRenderState = new RenderState(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
|
int RenderThread::displayEventReceiverCallback(int fd, int events, void* data) {
|
||||||
|
Reference in New Issue
Block a user