Add initial OpReorderer benchmarks

Change-Id: I6ca8ea89be2159331b2ad7031769c65f54161918
This commit is contained in:
Chris Craik
2015-10-19 17:10:19 -07:00
parent ec3d759a34
commit 0a24b146cd
6 changed files with 124 additions and 8 deletions

View File

@@ -263,4 +263,9 @@ LOCAL_SRC_FILES += \
microbench/DisplayListCanvasBench.cpp \
microbench/LinearAllocatorBench.cpp
ifeq (true, $(HWUI_NEW_OPS))
LOCAL_SRC_FILES += \
microbench/OpReordererBench.cpp
endif
include $(BUILD_EXECUTABLE)

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2015 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 <benchmark/Benchmark.h>
#include "BakedOpState.h"
#include "BakedOpRenderer.h"
#include "OpReorderer.h"
#include "RecordedOp.h"
#include "RecordingCanvas.h"
#include "unit_tests/TestUtils.h"
#include "microbench/MicroBench.h"
#include <vector>
using namespace android;
using namespace android::uirenderer;
auto sReorderingDisplayList = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
SkBitmap bitmap = TestUtils::createSkBitmap(10, 10);
SkPaint paint;
// Alternate between drawing rects and bitmaps, with bitmaps overlapping rects.
// Rects don't overlap bitmaps, so bitmaps should be brought to front as a group.
canvas.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
for (int i = 0; i < 30; i++) {
canvas.translate(0, 10);
canvas.drawRect(0, 0, 10, 10, paint);
canvas.drawBitmap(bitmap, 5, 0, nullptr);
}
canvas.restore();
});
BENCHMARK_NO_ARG(BM_OpReorderer_defer);
void BM_OpReorderer_defer::Run(int iters) {
StartBenchmarkTiming();
for (int i = 0; i < iters; i++) {
OpReorderer reorderer;
reorderer.defer(200, 200, *sReorderingDisplayList);
MicroBench::DoNotOptimize(&reorderer);
}
StopBenchmarkTiming();
}
BENCHMARK_NO_ARG(BM_OpReorderer_deferAndRender);
void BM_OpReorderer_deferAndRender::Run(int iters) {
TestUtils::runOnRenderThread([this, iters](RenderState& renderState, Caches& caches) {
StartBenchmarkTiming();
for (int i = 0; i < iters; i++) {
OpReorderer reorderer;
reorderer.defer(200, 200, *sReorderingDisplayList);
MicroBench::DoNotOptimize(&reorderer);
BakedOpRenderer::Info info(caches, renderState, 200, 200, true);
reorderer.replayBakedOps<BakedOpRenderer>(&info);
}
StopBenchmarkTiming();
});
}

View File

@@ -574,12 +574,7 @@ 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);
thread.queueAndWait(task);
return retval;
}

View File

@@ -312,6 +312,16 @@ void RenderThread::queue(RenderTask* task) {
}
}
void RenderThread::queueAndWait(RenderTask* task) {
Mutex mutex;
Condition condition;
SignalingRenderTask syncTask(task, &mutex, &condition);
AutoMutex _lock(mutex);
queue(&syncTask);
condition.wait(mutex);
}
void RenderThread::queueAtFront(RenderTask* task) {
AutoMutex _lock(mLock);
mQueue.queueAtFront(task);

View File

@@ -39,6 +39,7 @@ class DisplayEventReceiver;
namespace uirenderer {
class RenderState;
class TestUtils;
namespace renderthread {
@@ -76,6 +77,7 @@ public:
// RenderThread takes complete ownership of tasks that are queued
// and will delete them after they are run
ANDROID_API void queue(RenderTask* task);
ANDROID_API void queueAndWait(RenderTask* task);
ANDROID_API void queueAtFront(RenderTask* task);
void queueAt(RenderTask* task, nsecs_t runAtNs);
void remove(RenderTask* task);
@@ -101,6 +103,7 @@ private:
friend class Singleton<RenderThread>;
friend class DispatchFrameCallbacks;
friend class RenderProxy;
friend class android::uirenderer::TestUtils;
RenderThread();
virtual ~RenderThread();

View File

@@ -17,8 +17,11 @@
#define TEST_UTILS_H
#include <Matrix.h>
#include <Snapshot.h>
#include <Rect.h>
#include <RenderNode.h>
#include <renderstate/RenderState.h>
#include <renderthread/RenderThread.h>
#include <Snapshot.h>
#include <memory>
@@ -48,7 +51,9 @@ public:
static SkBitmap createSkBitmap(int width, int height) {
SkBitmap bitmap;
bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
SkImageInfo info = SkImageInfo::MakeUnknown(width, height);
bitmap.setInfo(info);
bitmap.allocPixels(info);
return bitmap;
}
@@ -78,6 +83,32 @@ public:
node->syncProperties();
node->syncDisplayList();
}
typedef std::function<void(RenderState& state, Caches& caches)> RtCallback;
class TestTask : public renderthread::RenderTask {
public:
TestTask(RtCallback rtCallback)
: rtCallback(rtCallback) {}
virtual ~TestTask() {}
virtual void run() override {
// RenderState only valid once RenderThread is running, so queried here
RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
renderState.onGLContextCreated();
rtCallback(renderState, Caches::getInstance());
renderState.onGLContextDestroyed();
};
RtCallback rtCallback;
};
/**
* NOTE: requires surfaceflinger to run, otherwise this method will wait indefinitely.
*/
static void runOnRenderThread(RtCallback rtCallback) {
TestTask task(rtCallback);
renderthread::RenderThread::getInstance().queueAndWait(&task);
}
}; // class TestUtils
} /* namespace uirenderer */