Add initial OpReorderer benchmarks
Change-Id: I6ca8ea89be2159331b2ad7031769c65f54161918
This commit is contained in:
@@ -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)
|
||||
|
||||
72
libs/hwui/microbench/OpReordererBench.cpp
Normal file
72
libs/hwui/microbench/OpReordererBench.cpp
Normal 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();
|
||||
});
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user