2014-01-03 18:09:17 -08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2013 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "RenderProxy.h"
|
|
|
|
|
2015-02-19 14:36:50 -08:00
|
|
|
#include "DeferredLayerUpdater.h"
|
|
|
|
#include "DisplayList.h"
|
|
|
|
#include "LayerRenderer.h"
|
|
|
|
#include "Rect.h"
|
|
|
|
#include "renderthread/CanvasContext.h"
|
|
|
|
#include "renderthread/RenderTask.h"
|
|
|
|
#include "renderthread/RenderThread.h"
|
|
|
|
#include "utils/Macros.h"
|
2014-01-03 18:09:17 -08:00
|
|
|
|
|
|
|
namespace android {
|
|
|
|
namespace uirenderer {
|
|
|
|
namespace renderthread {
|
|
|
|
|
|
|
|
#define ARGS(method) method ## Args
|
|
|
|
|
2014-02-14 20:03:38 -08:00
|
|
|
#define CREATE_BRIDGE0(name) CREATE_BRIDGE(name,,,,,,,,)
|
2014-01-03 18:09:17 -08:00
|
|
|
#define CREATE_BRIDGE1(name, a1) CREATE_BRIDGE(name, a1,,,,,,,)
|
|
|
|
#define CREATE_BRIDGE2(name, a1, a2) CREATE_BRIDGE(name, a1,a2,,,,,,)
|
|
|
|
#define CREATE_BRIDGE3(name, a1, a2, a3) CREATE_BRIDGE(name, a1,a2,a3,,,,,)
|
|
|
|
#define CREATE_BRIDGE4(name, a1, a2, a3, a4) CREATE_BRIDGE(name, a1,a2,a3,a4,,,,)
|
2014-05-20 18:10:25 -07:00
|
|
|
#define CREATE_BRIDGE5(name, a1, a2, a3, a4, a5) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,,,)
|
2014-07-23 18:19:28 -07:00
|
|
|
#define CREATE_BRIDGE6(name, a1, a2, a3, a4, a5, a6) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,a6,,)
|
|
|
|
#define CREATE_BRIDGE7(name, a1, a2, a3, a4, a5, a6, a7) CREATE_BRIDGE(name, a1,a2,a3,a4,a5,a6,a7,)
|
2014-01-03 18:09:17 -08:00
|
|
|
#define CREATE_BRIDGE(name, a1, a2, a3, a4, a5, a6, a7, a8) \
|
|
|
|
typedef struct { \
|
|
|
|
a1; a2; a3; a4; a5; a6; a7; a8; \
|
|
|
|
} ARGS(name); \
|
|
|
|
static void* Bridge_ ## name(ARGS(name)* args)
|
|
|
|
|
|
|
|
#define SETUP_TASK(method) \
|
|
|
|
LOG_ALWAYS_FATAL_IF( METHOD_INVOKE_PAYLOAD_SIZE < sizeof(ARGS(method)), \
|
2014-06-10 12:29:14 -07:00
|
|
|
"METHOD_INVOKE_PAYLOAD_SIZE %zu is smaller than sizeof(" #method "Args) %zu", \
|
2014-01-03 18:09:17 -08:00
|
|
|
METHOD_INVOKE_PAYLOAD_SIZE, sizeof(ARGS(method))); \
|
2014-04-07 17:31:44 -07:00
|
|
|
MethodInvokeRenderTask* task = new MethodInvokeRenderTask((RunnableMethod) Bridge_ ## method); \
|
2014-01-03 18:09:17 -08:00
|
|
|
ARGS(method) *args = (ARGS(method) *) task->payload()
|
|
|
|
|
2015-02-20 10:57:22 -08:00
|
|
|
enum class DumpFlags {
|
2015-02-19 14:36:50 -08:00
|
|
|
kFrameStats = 1 << 0,
|
|
|
|
kReset = 1 << 1,
|
2015-02-20 10:57:22 -08:00
|
|
|
};
|
|
|
|
MAKE_FLAGS_ENUM(DumpFlags)
|
2015-02-19 14:36:50 -08:00
|
|
|
|
2014-08-14 09:02:01 -07:00
|
|
|
CREATE_BRIDGE4(createContext, RenderThread* thread, bool translucent,
|
|
|
|
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
|
|
|
|
return new CanvasContext(*args->thread, args->translucent,
|
|
|
|
args->rootRenderNode, args->contextFactory);
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-08-14 09:02:01 -07:00
|
|
|
RenderProxy::RenderProxy(bool translucent, RenderNode* rootRenderNode, IContextFactory* contextFactory)
|
2014-01-03 18:09:17 -08:00
|
|
|
: mRenderThread(RenderThread::getInstance())
|
2015-01-05 15:51:13 -08:00
|
|
|
, mContext(nullptr) {
|
2014-01-03 18:09:17 -08:00
|
|
|
SETUP_TASK(createContext);
|
|
|
|
args->translucent = translucent;
|
2014-04-15 09:50:16 -07:00
|
|
|
args->rootRenderNode = rootRenderNode;
|
2014-06-23 13:13:08 -07:00
|
|
|
args->thread = &mRenderThread;
|
2014-08-14 09:02:01 -07:00
|
|
|
args->contextFactory = contextFactory;
|
2014-01-03 18:09:17 -08:00
|
|
|
mContext = (CanvasContext*) postAndWait(task);
|
2014-05-02 16:46:41 -07:00
|
|
|
mDrawFrameTask.setContext(&mRenderThread, mContext);
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
RenderProxy::~RenderProxy() {
|
|
|
|
destroyContext();
|
|
|
|
}
|
|
|
|
|
|
|
|
CREATE_BRIDGE1(destroyContext, CanvasContext* context) {
|
|
|
|
delete args->context;
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::destroyContext() {
|
|
|
|
if (mContext) {
|
|
|
|
SETUP_TASK(destroyContext);
|
|
|
|
args->context = mContext;
|
2015-01-05 15:51:13 -08:00
|
|
|
mContext = nullptr;
|
|
|
|
mDrawFrameTask.setContext(nullptr, nullptr);
|
2014-03-26 15:10:40 -07:00
|
|
|
// This is also a fence as we need to be certain that there are no
|
|
|
|
// outstanding mDrawFrame tasks posted before it is destroyed
|
|
|
|
postAndWait(task);
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-23 11:02:19 -07:00
|
|
|
CREATE_BRIDGE2(setSwapBehavior, CanvasContext* context, SwapBehavior swapBehavior) {
|
|
|
|
args->context->setSwapBehavior(args->swapBehavior);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-10-23 11:02:19 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
|
|
|
|
SETUP_TASK(setSwapBehavior);
|
|
|
|
args->context = mContext;
|
|
|
|
args->swapBehavior = swapBehavior;
|
|
|
|
post(task);
|
|
|
|
}
|
|
|
|
|
2014-05-23 17:42:28 -07:00
|
|
|
CREATE_BRIDGE1(loadSystemProperties, CanvasContext* context) {
|
2014-05-05 16:39:37 -07:00
|
|
|
bool needsRedraw = false;
|
|
|
|
if (Caches::hasInstance()) {
|
|
|
|
needsRedraw = Caches::getInstance().initProperties();
|
|
|
|
}
|
2014-05-23 17:42:28 -07:00
|
|
|
if (args->context->profiler().loadSystemProperties()) {
|
|
|
|
needsRedraw = true;
|
|
|
|
}
|
2014-05-05 16:39:37 -07:00
|
|
|
return (void*) needsRedraw;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RenderProxy::loadSystemProperties() {
|
|
|
|
SETUP_TASK(loadSystemProperties);
|
2014-05-23 17:42:28 -07:00
|
|
|
args->context = mContext;
|
2014-05-05 16:39:37 -07:00
|
|
|
return (bool) postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2015-03-11 08:50:53 -07:00
|
|
|
CREATE_BRIDGE2(setName, CanvasContext* context, const char* name) {
|
|
|
|
args->context->setName(std::string(args->name));
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::setName(const char* name) {
|
|
|
|
SETUP_TASK(setName);
|
|
|
|
args->context = mContext;
|
|
|
|
args->name = name;
|
2015-05-04 09:44:28 -07:00
|
|
|
postAndWait(task);
|
2015-03-11 08:50:53 -07:00
|
|
|
}
|
|
|
|
|
2014-05-22 15:43:54 -07:00
|
|
|
CREATE_BRIDGE2(initialize, CanvasContext* context, ANativeWindow* window) {
|
2014-01-03 18:09:17 -08:00
|
|
|
return (void*) args->context->initialize(args->window);
|
|
|
|
}
|
|
|
|
|
2014-04-09 10:01:03 -07:00
|
|
|
bool RenderProxy::initialize(const sp<ANativeWindow>& window) {
|
2014-01-03 18:09:17 -08:00
|
|
|
SETUP_TASK(initialize);
|
|
|
|
args->context = mContext;
|
2014-04-09 10:01:03 -07:00
|
|
|
args->window = window.get();
|
2014-01-03 18:09:17 -08:00
|
|
|
return (bool) postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-05-22 15:43:54 -07:00
|
|
|
CREATE_BRIDGE2(updateSurface, CanvasContext* context, ANativeWindow* window) {
|
2014-01-03 18:09:17 -08:00
|
|
|
args->context->updateSurface(args->window);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-04-09 10:01:03 -07:00
|
|
|
void RenderProxy::updateSurface(const sp<ANativeWindow>& window) {
|
2014-01-03 18:09:17 -08:00
|
|
|
SETUP_TASK(updateSurface);
|
|
|
|
args->context = mContext;
|
2014-04-09 10:01:03 -07:00
|
|
|
args->window = window.get();
|
|
|
|
postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-05-22 15:43:54 -07:00
|
|
|
CREATE_BRIDGE2(pauseSurface, CanvasContext* context, ANativeWindow* window) {
|
2014-12-03 13:01:07 -08:00
|
|
|
return (void*) args->context->pauseSurface(args->window);
|
2014-04-09 10:01:03 -07:00
|
|
|
}
|
|
|
|
|
2014-12-03 13:01:07 -08:00
|
|
|
bool RenderProxy::pauseSurface(const sp<ANativeWindow>& window) {
|
2014-04-09 10:01:03 -07:00
|
|
|
SETUP_TASK(pauseSurface);
|
|
|
|
args->context = mContext;
|
|
|
|
args->window = window.get();
|
2014-12-03 13:01:07 -08:00
|
|
|
return (bool) postAndWait(task);
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-07-23 18:19:28 -07:00
|
|
|
CREATE_BRIDGE7(setup, CanvasContext* context, int width, int height,
|
|
|
|
Vector3 lightCenter, float lightRadius,
|
|
|
|
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
|
|
|
|
args->context->setup(args->width, args->height, args->lightCenter, args->lightRadius,
|
|
|
|
args->ambientShadowAlpha, args->spotShadowAlpha);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-07-23 18:19:28 -07:00
|
|
|
void RenderProxy::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
|
2015-03-11 08:50:53 -07:00
|
|
|
uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha) {
|
2014-01-03 18:09:17 -08:00
|
|
|
SETUP_TASK(setup);
|
|
|
|
args->context = mContext;
|
|
|
|
args->width = width;
|
|
|
|
args->height = height;
|
2014-05-20 18:10:25 -07:00
|
|
|
args->lightCenter = lightCenter;
|
|
|
|
args->lightRadius = lightRadius;
|
2014-07-23 18:19:28 -07:00
|
|
|
args->ambientShadowAlpha = ambientShadowAlpha;
|
|
|
|
args->spotShadowAlpha = spotShadowAlpha;
|
2014-01-03 18:09:17 -08:00
|
|
|
post(task);
|
|
|
|
}
|
|
|
|
|
2014-05-07 13:45:54 -07:00
|
|
|
CREATE_BRIDGE2(setOpaque, CanvasContext* context, bool opaque) {
|
|
|
|
args->context->setOpaque(args->opaque);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-05-07 13:45:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::setOpaque(bool opaque) {
|
|
|
|
SETUP_TASK(setOpaque);
|
|
|
|
args->context = mContext;
|
|
|
|
args->opaque = opaque;
|
|
|
|
post(task);
|
|
|
|
}
|
|
|
|
|
2015-02-19 14:36:50 -08:00
|
|
|
int64_t* RenderProxy::frameInfo() {
|
|
|
|
return mDrawFrameTask.frameInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
int RenderProxy::syncAndDrawFrame() {
|
|
|
|
return mDrawFrameTask.drawFrame();
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-09-03 07:39:53 -07:00
|
|
|
CREATE_BRIDGE1(destroy, CanvasContext* context) {
|
|
|
|
args->context->destroy();
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-09-03 07:39:53 -07:00
|
|
|
void RenderProxy::destroy() {
|
|
|
|
SETUP_TASK(destroy);
|
2014-01-03 18:09:17 -08:00
|
|
|
args->context = mContext;
|
2014-04-14 11:01:57 -07:00
|
|
|
// destroyCanvasAndSurface() needs a fence as when it returns the
|
|
|
|
// underlying BufferQueue is going to be released from under
|
|
|
|
// the render thread.
|
|
|
|
postAndWait(task);
|
2014-01-03 18:09:17 -08:00
|
|
|
}
|
|
|
|
|
2014-06-23 13:13:08 -07:00
|
|
|
CREATE_BRIDGE2(invokeFunctor, RenderThread* thread, Functor* functor) {
|
|
|
|
CanvasContext::invokeFunctor(*args->thread, args->functor);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-03-28 20:30:27 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::invokeFunctor(Functor* functor, bool waitForCompletion) {
|
2014-04-10 15:00:13 -07:00
|
|
|
ATRACE_CALL();
|
2014-06-23 13:13:08 -07:00
|
|
|
RenderThread& thread = RenderThread::getInstance();
|
2014-03-28 20:30:27 -07:00
|
|
|
SETUP_TASK(invokeFunctor);
|
2014-06-23 13:13:08 -07:00
|
|
|
args->thread = &thread;
|
2014-03-28 20:30:27 -07:00
|
|
|
args->functor = functor;
|
|
|
|
if (waitForCompletion) {
|
2014-06-23 13:13:08 -07:00
|
|
|
// waitForCompletion = true is expected to be fairly rare and only
|
|
|
|
// happen in destruction. Thus it should be fine to temporarily
|
|
|
|
// create a Mutex
|
2014-10-31 14:49:06 -07:00
|
|
|
staticPostAndWait(task);
|
2014-03-28 20:30:27 -07:00
|
|
|
} else {
|
2014-06-23 13:13:08 -07:00
|
|
|
thread.queue(task);
|
2014-03-28 20:30:27 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-11 10:40:25 -08:00
|
|
|
CREATE_BRIDGE2(runWithGlContext, CanvasContext* context, RenderTask* task) {
|
|
|
|
args->context->runWithGlContext(args->task);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-02-11 10:40:25 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::runWithGlContext(RenderTask* gltask) {
|
|
|
|
SETUP_TASK(runWithGlContext);
|
|
|
|
args->context = mContext;
|
|
|
|
args->task = gltask;
|
|
|
|
postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-10-03 15:02:19 -07:00
|
|
|
CREATE_BRIDGE2(createTextureLayer, RenderThread* thread, CanvasContext* context) {
|
2014-04-08 15:18:56 -07:00
|
|
|
Layer* layer = args->context->createTextureLayer();
|
2015-01-05 15:51:13 -08:00
|
|
|
if (!layer) return nullptr;
|
2014-10-03 15:02:19 -07:00
|
|
|
return new DeferredLayerUpdater(*args->thread, layer);
|
2014-02-14 20:03:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
DeferredLayerUpdater* RenderProxy::createTextureLayer() {
|
|
|
|
SETUP_TASK(createTextureLayer);
|
2014-04-08 15:18:56 -07:00
|
|
|
args->context = mContext;
|
2014-10-03 15:02:19 -07:00
|
|
|
args->thread = &mRenderThread;
|
2014-02-14 20:03:38 -08:00
|
|
|
void* retval = postAndWait(task);
|
|
|
|
DeferredLayerUpdater* layer = reinterpret_cast<DeferredLayerUpdater*>(retval);
|
|
|
|
return layer;
|
|
|
|
}
|
|
|
|
|
2014-08-20 10:08:39 -07:00
|
|
|
CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
|
|
|
|
args->context->buildLayer(args->node);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-08-20 10:08:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::buildLayer(RenderNode* node) {
|
|
|
|
SETUP_TASK(buildLayer);
|
|
|
|
args->context = mContext;
|
|
|
|
args->node = node;
|
|
|
|
postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-02-14 20:03:38 -08:00
|
|
|
CREATE_BRIDGE3(copyLayerInto, CanvasContext* context, DeferredLayerUpdater* layer,
|
|
|
|
SkBitmap* bitmap) {
|
|
|
|
bool success = args->context->copyLayerInto(args->layer, args->bitmap);
|
|
|
|
return (void*) success;
|
|
|
|
}
|
|
|
|
|
2015-04-13 15:20:29 -07:00
|
|
|
bool RenderProxy::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap) {
|
2014-02-14 20:03:38 -08:00
|
|
|
SETUP_TASK(copyLayerInto);
|
|
|
|
args->context = mContext;
|
|
|
|
args->layer = layer;
|
2015-04-13 15:20:29 -07:00
|
|
|
args->bitmap = &bitmap;
|
2014-02-14 20:03:38 -08:00
|
|
|
return (bool) postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-05-29 18:56:11 -07:00
|
|
|
void RenderProxy::pushLayerUpdate(DeferredLayerUpdater* layer) {
|
|
|
|
mDrawFrameTask.pushLayerUpdate(layer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::cancelLayerUpdate(DeferredLayerUpdater* layer) {
|
|
|
|
mDrawFrameTask.removeLayerUpdate(layer);
|
2014-06-27 14:45:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
CREATE_BRIDGE1(detachSurfaceTexture, DeferredLayerUpdater* layer) {
|
|
|
|
args->layer->detachSurfaceTexture();
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-06-27 14:45:25 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
|
|
|
|
SETUP_TASK(detachSurfaceTexture);
|
|
|
|
args->layer = layer;
|
|
|
|
postAndWait(task);
|
2014-02-14 20:03:38 -08:00
|
|
|
}
|
|
|
|
|
2014-06-30 16:20:04 -07:00
|
|
|
CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) {
|
|
|
|
args->context->destroyHardwareResources();
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-05-23 15:11:19 -07:00
|
|
|
}
|
|
|
|
|
2014-06-30 16:20:04 -07:00
|
|
|
void RenderProxy::destroyHardwareResources() {
|
|
|
|
SETUP_TASK(destroyHardwareResources);
|
2014-05-23 15:11:19 -07:00
|
|
|
args->context = mContext;
|
|
|
|
post(task);
|
|
|
|
}
|
|
|
|
|
2014-06-30 16:20:04 -07:00
|
|
|
CREATE_BRIDGE2(timMemory, RenderThread* thread, int level) {
|
|
|
|
CanvasContext::trimMemory(*args->thread, args->level);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-06-30 16:20:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::trimMemory(int level) {
|
2014-08-06 13:33:59 -07:00
|
|
|
// Avoid creating a RenderThread to do a trimMemory.
|
|
|
|
if (RenderThread::hasInstance()) {
|
|
|
|
RenderThread& thread = RenderThread::getInstance();
|
|
|
|
SETUP_TASK(timMemory);
|
|
|
|
args->thread = &thread;
|
|
|
|
args->level = level;
|
|
|
|
thread.queue(task);
|
|
|
|
}
|
2014-06-30 16:20:04 -07:00
|
|
|
}
|
|
|
|
|
2014-04-07 16:59:25 -07:00
|
|
|
CREATE_BRIDGE0(fence) {
|
|
|
|
// Intentionally empty
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-04-07 16:59:25 -07:00
|
|
|
}
|
|
|
|
|
2014-11-22 00:35:09 +00:00
|
|
|
template <typename T>
|
|
|
|
void UNUSED(T t) {}
|
|
|
|
|
2014-04-07 16:59:25 -07:00
|
|
|
void RenderProxy::fence() {
|
|
|
|
SETUP_TASK(fence);
|
2014-11-10 15:23:43 -08:00
|
|
|
UNUSED(args);
|
2014-04-07 16:59:25 -07:00
|
|
|
postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-06-30 16:20:04 -07:00
|
|
|
CREATE_BRIDGE1(stopDrawing, CanvasContext* context) {
|
|
|
|
args->context->stopDrawing();
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-06-30 16:20:04 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::stopDrawing() {
|
|
|
|
SETUP_TASK(stopDrawing);
|
|
|
|
args->context = mContext;
|
|
|
|
postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-05-22 15:43:54 -07:00
|
|
|
CREATE_BRIDGE1(notifyFramePending, CanvasContext* context) {
|
|
|
|
args->context->notifyFramePending();
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-05-22 15:43:54 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::notifyFramePending() {
|
|
|
|
SETUP_TASK(notifyFramePending);
|
|
|
|
args->context = mContext;
|
|
|
|
mRenderThread.queueAtFront(task);
|
|
|
|
}
|
|
|
|
|
2015-02-19 14:36:50 -08:00
|
|
|
CREATE_BRIDGE3(dumpProfileInfo, CanvasContext* context, int fd, int dumpFlags) {
|
2014-05-23 17:42:28 -07:00
|
|
|
args->context->profiler().dumpData(args->fd);
|
2015-02-19 14:36:50 -08:00
|
|
|
if (args->dumpFlags & DumpFlags::kFrameStats) {
|
|
|
|
args->context->dumpFrames(args->fd);
|
|
|
|
}
|
|
|
|
if (args->dumpFlags & DumpFlags::kReset) {
|
|
|
|
args->context->resetFrameStats();
|
|
|
|
}
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-05-23 17:42:28 -07:00
|
|
|
}
|
|
|
|
|
2015-02-19 14:36:50 -08:00
|
|
|
void RenderProxy::dumpProfileInfo(int fd, int dumpFlags) {
|
2014-05-23 17:42:28 -07:00
|
|
|
SETUP_TASK(dumpProfileInfo);
|
|
|
|
args->context = mContext;
|
|
|
|
args->fd = fd;
|
2015-02-19 14:36:50 -08:00
|
|
|
args->dumpFlags = dumpFlags;
|
2014-05-23 17:42:28 -07:00
|
|
|
postAndWait(task);
|
|
|
|
}
|
|
|
|
|
2015-02-19 14:36:50 -08:00
|
|
|
CREATE_BRIDGE2(dumpGraphicsMemory, int fd, RenderThread* thread) {
|
|
|
|
args->thread->jankTracker().dump(args->fd);
|
|
|
|
|
2015-01-21 14:22:39 -08:00
|
|
|
FILE *file = fdopen(args->fd, "a");
|
|
|
|
if (Caches::hasInstance()) {
|
|
|
|
String8 cachesLog;
|
|
|
|
Caches::getInstance().dumpMemoryUsage(cachesLog);
|
|
|
|
fprintf(file, "\nCaches:\n%s\n", cachesLog.string());
|
|
|
|
} else {
|
|
|
|
fprintf(file, "\nNo caches instance.\n");
|
|
|
|
}
|
|
|
|
fflush(file);
|
2015-01-05 15:51:13 -08:00
|
|
|
return nullptr;
|
2014-10-31 14:49:06 -07:00
|
|
|
}
|
|
|
|
|
2015-01-21 14:22:39 -08:00
|
|
|
void RenderProxy::dumpGraphicsMemory(int fd) {
|
Don't create unnecessary RenderThread's instance when executing 'dumpsys gfxinfo'
To obtain the gfxinfo for each process, the static method of RenderProxy is used, which is named outputLogBuffer().
In there,
1. RenderTask is created for getting DisplayList Commands in RenderNode.
2. staticPostAndWait() is called
3. RenderThread's instance is created by 'RenderThread::getInstance()' in staticPostAndWait()
In case of the service, they don't use HW Acceleration, so don't need RenderThread.
But, by the process of No.3, RenderThread is created for all process.
As we know, RenderThread never be destroyed while the process is alive.
This patch checks RenderThread instance before the creation of RenderTask.
And, there is no one, just return to prevent the unnecessay creation of it.
Change-Id: I4fe29d83c9ced3e8b67177c0874c5d8ee62e1870
2015-03-20 21:22:32 +09:00
|
|
|
if (!RenderThread::hasInstance()) return;
|
2015-01-21 14:22:39 -08:00
|
|
|
SETUP_TASK(dumpGraphicsMemory);
|
2014-10-31 14:49:06 -07:00
|
|
|
args->fd = fd;
|
2015-02-19 14:36:50 -08:00
|
|
|
args->thread = &RenderThread::getInstance();
|
2014-10-31 14:49:06 -07:00
|
|
|
staticPostAndWait(task);
|
|
|
|
}
|
|
|
|
|
2014-06-23 13:13:08 -07:00
|
|
|
CREATE_BRIDGE4(setTextureAtlas, RenderThread* thread, GraphicBuffer* buffer, int64_t* map, size_t size) {
|
|
|
|
CanvasContext::setTextureAtlas(*args->thread, args->buffer, args->map, args->size);
|
2015-01-05 15:51:13 -08:00
|
|
|
args->buffer->decStrong(nullptr);
|
|
|
|
return nullptr;
|
2014-06-23 13:13:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t size) {
|
|
|
|
SETUP_TASK(setTextureAtlas);
|
|
|
|
args->thread = &mRenderThread;
|
|
|
|
args->buffer = buffer.get();
|
2015-01-05 15:51:13 -08:00
|
|
|
args->buffer->incStrong(nullptr);
|
2014-06-23 13:13:08 -07:00
|
|
|
args->map = map;
|
|
|
|
args->size = size;
|
|
|
|
post(task);
|
|
|
|
}
|
|
|
|
|
2015-03-18 15:24:33 -07:00
|
|
|
CREATE_BRIDGE2(setProcessStatsBuffer, RenderThread* thread, int fd) {
|
|
|
|
args->thread->jankTracker().switchStorageToAshmem(args->fd);
|
|
|
|
close(args->fd);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RenderProxy::setProcessStatsBuffer(int fd) {
|
|
|
|
SETUP_TASK(setProcessStatsBuffer);
|
|
|
|
args->thread = &mRenderThread;
|
|
|
|
args->fd = dup(fd);
|
|
|
|
post(task);
|
|
|
|
}
|
|
|
|
|
2014-01-03 18:09:17 -08:00
|
|
|
void RenderProxy::post(RenderTask* task) {
|
|
|
|
mRenderThread.queue(task);
|
|
|
|
}
|
|
|
|
|
|
|
|
void* RenderProxy::postAndWait(MethodInvokeRenderTask* task) {
|
|
|
|
void* retval;
|
|
|
|
task->setReturnPtr(&retval);
|
|
|
|
SignalingRenderTask syncTask(task, &mSyncMutex, &mSyncCondition);
|
|
|
|
AutoMutex _lock(mSyncMutex);
|
2014-07-25 18:25:02 +00:00
|
|
|
mRenderThread.queue(&syncTask);
|
|
|
|
mSyncCondition.wait(mSyncMutex);
|
2014-01-03 18:09:17 -08:00
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2014-10-31 14:49:06 -07:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-01-03 18:09:17 -08:00
|
|
|
} /* namespace renderthread */
|
|
|
|
} /* namespace uirenderer */
|
|
|
|
} /* namespace android */
|