diff options
author | 2015-10-16 16:57:23 +0000 | |
---|---|---|
committer | 2015-10-16 16:57:23 +0000 | |
commit | e4436e325c7756b162d99b05ece3dd9c38ce3a44 (patch) | |
tree | 0ac3de6e0b24d8542cdbbcd3df587e4cb20a257e | |
parent | c4c7aa14afa704952babd9808b8fc17e4f96890e (diff) | |
parent | 81a1d2a15927b06b84359f839ab03ac8a20970bd (diff) |
Merge "Add LinearStdAllocator"
-rw-r--r-- | libs/hwui/Android.mk | 3 | ||||
-rw-r--r-- | libs/hwui/DisplayListCanvas.h | 3 | ||||
-rw-r--r-- | libs/hwui/RecordingCanvas.h | 2 | ||||
-rw-r--r-- | libs/hwui/microbench/DisplayListCanvasBench.cpp | 13 | ||||
-rw-r--r-- | libs/hwui/microbench/LinearAllocatorBench.cpp | 53 | ||||
-rw-r--r-- | libs/hwui/unit_tests/LinearAllocatorTests.cpp | 28 | ||||
-rw-r--r-- | libs/hwui/utils/LinearAllocator.cpp | 18 | ||||
-rw-r--r-- | libs/hwui/utils/LinearAllocator.h | 41 |
8 files changed, 141 insertions, 20 deletions
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 6f548bcabedc..9fc3924e8efd 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -254,6 +254,7 @@ LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static LOCAL_STATIC_LIBRARIES := libbenchmark libbase LOCAL_SRC_FILES += \ - microbench/DisplayListCanvasBench.cpp + microbench/DisplayListCanvasBench.cpp \ + microbench/LinearAllocatorBench.cpp include $(BUILD_EXECUTABLE) diff --git a/libs/hwui/DisplayListCanvas.h b/libs/hwui/DisplayListCanvas.h index 392bb3e5d85f..8f4ae3da8561 100644 --- a/libs/hwui/DisplayListCanvas.h +++ b/libs/hwui/DisplayListCanvas.h @@ -66,8 +66,7 @@ public: virtual ~DisplayListCanvas(); void reset(int width, int height); - - DisplayListData* finishRecording(); + __attribute__((warn_unused_result)) DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- // HWUI Canvas state operations diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h index ed299e56ce7c..8f44ff07f135 100644 --- a/libs/hwui/RecordingCanvas.h +++ b/libs/hwui/RecordingCanvas.h @@ -41,7 +41,7 @@ public: virtual ~RecordingCanvas(); void reset(int width, int height); - DisplayListData* finishRecording(); + __attribute__((warn_unused_result)) DisplayListData* finishRecording(); // ---------------------------------------------------------------------------- // MISC HWUI OPERATIONS - TODO: CATEGORIZE diff --git a/libs/hwui/microbench/DisplayListCanvasBench.cpp b/libs/hwui/microbench/DisplayListCanvasBench.cpp index fd42adb13da2..dccbe0b53874 100644 --- a/libs/hwui/microbench/DisplayListCanvasBench.cpp +++ b/libs/hwui/microbench/DisplayListCanvasBench.cpp @@ -15,7 +15,6 @@ */ #include <benchmark/Benchmark.h> -#include <utils/Singleton.h> #include "DisplayList.h" #if HWUI_NEW_OPS @@ -59,13 +58,13 @@ void BM_DisplayListData_alloc_theoretical::Run(int iters) { BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_empty); void BM_DisplayListCanvas_record_empty::Run(int iters) { TestCanvas canvas(100, 100); - canvas.finishRecording(); + delete canvas.finishRecording(); StartBenchmarkTiming(); for (int i = 0; i < iters; ++i) { canvas.reset(100, 100); MicroBench::DoNotOptimize(&canvas); - canvas.finishRecording(); + delete canvas.finishRecording(); } StopBenchmarkTiming(); } @@ -73,7 +72,7 @@ void BM_DisplayListCanvas_record_empty::Run(int iters) { BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_saverestore); void BM_DisplayListCanvas_record_saverestore::Run(int iters) { TestCanvas canvas(100, 100); - canvas.finishRecording(); + delete canvas.finishRecording(); StartBenchmarkTiming(); for (int i = 0; i < iters; ++i) { @@ -83,7 +82,7 @@ void BM_DisplayListCanvas_record_saverestore::Run(int iters) { MicroBench::DoNotOptimize(&canvas); canvas.restore(); canvas.restore(); - canvas.finishRecording(); + delete canvas.finishRecording(); } StopBenchmarkTiming(); } @@ -91,14 +90,14 @@ void BM_DisplayListCanvas_record_saverestore::Run(int iters) { BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_translate); void BM_DisplayListCanvas_record_translate::Run(int iters) { TestCanvas canvas(100, 100); - canvas.finishRecording(); + delete canvas.finishRecording(); StartBenchmarkTiming(); for (int i = 0; i < iters; ++i) { canvas.reset(100, 100); canvas.scale(10, 10); MicroBench::DoNotOptimize(&canvas); - canvas.finishRecording(); + delete canvas.finishRecording(); } StopBenchmarkTiming(); } diff --git a/libs/hwui/microbench/LinearAllocatorBench.cpp b/libs/hwui/microbench/LinearAllocatorBench.cpp new file mode 100644 index 000000000000..75f57cbd6021 --- /dev/null +++ b/libs/hwui/microbench/LinearAllocatorBench.cpp @@ -0,0 +1,53 @@ +/* + * 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 "utils/LinearAllocator.h" +#include "microbench/MicroBench.h" + +#include <vector> + +using namespace android; +using namespace android::uirenderer; + +BENCHMARK_NO_ARG(BM_LinearStdAllocator_vectorBaseline); +void BM_LinearStdAllocator_vectorBaseline::Run(int iters) { + StartBenchmarkTiming(); + for (int i = 0; i < iters; i++) { + std::vector<char> v; + for (int j = 0; j < 200; j++) { + v.push_back(j); + } + MicroBench::DoNotOptimize(&v); + } + StopBenchmarkTiming(); +} + +BENCHMARK_NO_ARG(BM_LinearStdAllocator_vector); +void BM_LinearStdAllocator_vector::Run(int iters) { + StartBenchmarkTiming(); + for (int i = 0; i < iters; i++) { + LinearAllocator la; + LinearStdAllocator<void*> stdAllocator(la); + std::vector<char, LinearStdAllocator<char> > v(stdAllocator); + for (int j = 0; j < 200; j++) { + v.push_back(j); + } + MicroBench::DoNotOptimize(&v); + } + StopBenchmarkTiming(); +} diff --git a/libs/hwui/unit_tests/LinearAllocatorTests.cpp b/libs/hwui/unit_tests/LinearAllocatorTests.cpp index b3959d169e1d..02cd77ae93db 100644 --- a/libs/hwui/unit_tests/LinearAllocatorTests.cpp +++ b/libs/hwui/unit_tests/LinearAllocatorTests.cpp @@ -106,3 +106,31 @@ TEST(LinearAllocator, rewind) { // Checking for a double-destroy case EXPECT_EQ(destroyed, false); } + +TEST(LinearStdAllocator, simpleAllocate) { + LinearAllocator la; + LinearStdAllocator<void*> stdAllocator(la); + + std::vector<char, LinearStdAllocator<char> > v(stdAllocator); + v.push_back(0); + char* initialLocation = &v[0]; + v.push_back(10); + v.push_back(20); + v.push_back(30); + + // expect to have allocated (since no space reserved), so [0] will have moved to + // slightly further down in the same LinearAllocator page + EXPECT_LT(initialLocation, &v[0]); + EXPECT_GT(initialLocation + 20, &v[0]); + + // expect to have allocated again inserting 4 more entries + char* lastLocation = &v[0]; + v.push_back(40); + v.push_back(50); + v.push_back(60); + v.push_back(70); + + EXPECT_LT(lastLocation, &v[0]); + EXPECT_GT(lastLocation + 20, &v[0]); + +} diff --git a/libs/hwui/utils/LinearAllocator.cpp b/libs/hwui/utils/LinearAllocator.cpp index 0abe88ba3fbb..e6a4c03156b4 100644 --- a/libs/hwui/utils/LinearAllocator.cpp +++ b/libs/hwui/utils/LinearAllocator.cpp @@ -52,8 +52,8 @@ #define ALIGN_PTR(p) ((void*)(ALIGN((size_t)p))) #if LOG_NDEBUG -#define ADD_ALLOCATION(size) -#define RM_ALLOCATION(size) +#define ADD_ALLOCATION() +#define RM_ALLOCATION() #else #include <utils/Thread.h> #include <utils/Timers.h> @@ -65,18 +65,18 @@ static void _logUsageLocked() { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); if (now > s_nextLog) { s_nextLog = now + milliseconds_to_nanoseconds(10); - ALOGV("Total memory usage: %zu kb", s_totalAllocations / 1024); + ALOGV("Total pages allocated: %zu", s_totalAllocations); } } -static void _addAllocation(size_t size) { +static void _addAllocation(int count) { android::AutoMutex lock(s_mutex); - s_totalAllocations += size; + s_totalAllocations += count; _logUsageLocked(); } -#define ADD_ALLOCATION(size) _addAllocation(size); -#define RM_ALLOCATION(size) _addAllocation(-size); +#define ADD_ALLOCATION(size) _addAllocation(1); +#define RM_ALLOCATION(size) _addAllocation(-1); #endif #define min(x,y) (((x) < (y)) ? (x) : (y)) @@ -134,7 +134,7 @@ LinearAllocator::~LinearAllocator(void) { Page* next = p->next(); p->~Page(); free(p); - RM_ALLOCATION(mPageSize); + RM_ALLOCATION(); p = next; } } @@ -238,7 +238,7 @@ void LinearAllocator::rewindIfLastAlloc(void* ptr, size_t allocSize) { LinearAllocator::Page* LinearAllocator::newPage(size_t pageSize) { pageSize = ALIGN(pageSize + sizeof(LinearAllocator::Page)); - ADD_ALLOCATION(pageSize); + ADD_ALLOCATION(); mTotalAllocated += pageSize; mPageCount++; void* buf = malloc(pageSize); diff --git a/libs/hwui/utils/LinearAllocator.h b/libs/hwui/utils/LinearAllocator.h index d90dd825ea1d..ade4ab308d86 100644 --- a/libs/hwui/utils/LinearAllocator.h +++ b/libs/hwui/utils/LinearAllocator.h @@ -134,6 +134,47 @@ private: size_t mDedicatedPageCount; }; +template <class T> +class LinearStdAllocator { +public: + typedef T value_type; // needed to implement std::allocator + typedef T* pointer; // needed to implement std::allocator + + LinearStdAllocator(LinearAllocator& allocator) + : linearAllocator(allocator) {} + LinearStdAllocator(const LinearStdAllocator& other) + : linearAllocator(other.linearAllocator) {} + ~LinearStdAllocator() {} + + // rebind marks that allocators can be rebound to different types + template <class U> + struct rebind { + typedef LinearStdAllocator<U> other; + }; + // enable allocators to be constructed from other templated types + template <class U> + LinearStdAllocator(const LinearStdAllocator<U>& other) + : linearAllocator(other.linearAllocator) {} + + T* allocate(size_t num, const void* = 0) { + return (T*)(linearAllocator.alloc(num * sizeof(T))); + } + + void deallocate(pointer p, size_t num) { + // attempt to rewind, but no guarantees + linearAllocator.rewindIfLastAlloc(p, num * sizeof(T)); + } + + // public so template copy constructor can access + LinearAllocator& linearAllocator; +}; + +// return that all specializations of LinearStdAllocator are interchangeable +template <class T1, class T2> +bool operator== (const LinearStdAllocator<T1>&, const LinearStdAllocator<T2>&) { return true; } +template <class T1, class T2> +bool operator!= (const LinearStdAllocator<T1>&, const LinearStdAllocator<T2>&) { return false; } + }; // namespace uirenderer }; // namespace android |