Merge "Add perf test for Typeface serialization."

This commit is contained in:
TreeHugger Robot
2020-11-21 01:05:22 +00:00
committed by Android (Google) Code Review
3 changed files with 121 additions and 2 deletions

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2020 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.
*/
package android.graphics.perftests;
import android.graphics.Typeface;
import android.os.SharedMemory;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Map;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TypefaceSerializationPerfTest {
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
@Test
public void testSerializeFontMap() throws Exception {
Map<String, Typeface> systemFontMap = Typeface.getSystemFontMap();
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
Typeface.serializeFontMap(systemFontMap);
}
}
@Test
public void testDeserializeFontMap() throws Exception {
SharedMemory memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
ByteBuffer buffer = memory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
buffer.position(0);
Typeface.deserializeFontMap(buffer);
}
}
@Test
public void testSetSystemFontMap() throws Exception {
SharedMemory memory = null;
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
state.pauseTiming();
// Explicitly destroy lazy-loaded typefaces, so that we don't hit the mmap limit
// (max_map_count).
Typeface.destroySystemFontMap();
Typeface.loadPreinstalledSystemFontMap();
if (memory != null) {
memory.close();
}
memory = Typeface.serializeFontMap(Typeface.getSystemFontMap());
state.resumeTiming();
Typeface.setSystemFontMap(memory);
}
}
}

View File

@@ -169,6 +169,8 @@ public class Typeface {
@UnsupportedAppUsage
public long native_instance;
private Runnable mCleaner;
/** @hide */
@IntDef(value = {NORMAL, BOLD, ITALIC, BOLD_ITALIC})
@Retention(RetentionPolicy.SOURCE)
@@ -1120,7 +1122,7 @@ public class Typeface {
}
native_instance = ni;
sRegistry.registerNativeAllocation(this, native_instance);
mCleaner = sRegistry.registerNativeAllocation(this, native_instance);
mStyle = nativeGetStyle(ni);
mWeight = nativeGetWeight(ni);
}
@@ -1234,6 +1236,13 @@ public class Typeface {
bos.write(value & 0xFF);
}
/** @hide */
public static Map<String, Typeface> getSystemFontMap() {
synchronized (SYSTEM_FONT_MAP_LOCK) {
return sSystemFontMap;
}
}
/**
* Deserialize font map and set it as system font map. This method should be called at most once
* per process.
@@ -1294,13 +1303,33 @@ public class Typeface {
}
}
static {
/** @hide */
@VisibleForTesting
public static void destroySystemFontMap() {
synchronized (SYSTEM_FONT_MAP_LOCK) {
for (Typeface typeface : sSystemFontMap.values()) {
typeface.mCleaner.run();
}
sSystemFontMap.clear();
if (sSystemFontMapBuffer != null) {
SharedMemory.unmap(sSystemFontMapBuffer);
}
sSystemFontMapBuffer = null;
}
}
/** @hide */
public static void loadPreinstalledSystemFontMap() {
final HashMap<String, Typeface> systemFontMap = new HashMap<>();
initSystemDefaultTypefaces(systemFontMap, SystemFonts.getRawSystemFallbackMap(),
SystemFonts.getAliases());
setSystemFontMap(systemFontMap);
}
static {
loadPreinstalledSystemFontMap();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;

View File

@@ -159,6 +159,13 @@ static std::function<std::shared_ptr<minikin::MinikinFont>()> readMinikinFontSki
return [fontPath, fontIndex, axesPtr, axesCount]() -> std::shared_ptr<minikin::MinikinFont> {
std::string path(fontPath.data(), fontPath.size());
sk_sp<SkData> data = SkData::MakeFromFileName(path.c_str());
if (data == nullptr) {
// This may happen if:
// 1. When the process failed to open the file (e.g. invalid path or permission).
// 2. When the process failed to map the file (e.g. hitting max_map_count limit).
ALOGE("Failed to make SkData from file name: %s", path.c_str());
return nullptr;
}
const void* fontPtr = data->data();
size_t fontSize = data->size();
std::vector<minikin::FontVariation> axes(axesPtr, axesPtr + axesCount);