remove (dead) Font code
Test: make
Change-Id: Icdb0f2fc356459718f02569054b91eadcd6a15c2
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 065b822..3495c4f 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -75,7 +75,6 @@
cc_defaults {
name: "hwui_bugreport_font_cache_usage",
- srcs: ["font/FontCacheHistoryTracker.cpp"],
cflags: ["-DBUGREPORT_FONT_CACHE_USAGE"],
}
@@ -152,8 +151,6 @@
"hwui/AnimatedImageDrawable.cpp",
"hwui/AnimatedImageThread.cpp",
"hwui/Bitmap.cpp",
- "font/CacheTexture.cpp",
- "font/Font.cpp",
"hwui/Canvas.cpp",
"hwui/MinikinSkia.cpp",
"hwui/MinikinUtils.cpp",
@@ -215,11 +212,9 @@
"DeviceInfo.cpp",
"DisplayList.cpp",
"FboCache.cpp",
- "FontRenderer.cpp",
"FrameBuilder.cpp",
"FrameInfo.cpp",
"FrameInfoVisualizer.cpp",
- "GammaFontRenderer.cpp",
"GlLayer.cpp",
"GlopBuilder.cpp",
"GpuMemoryTracker.cpp",
@@ -259,7 +254,6 @@
"Snapshot.cpp",
"SpotShadow.cpp",
"TessellationCache.cpp",
- "TextDropShadowCache.cpp",
"Texture.cpp",
"TextureCache.cpp",
"VectorDrawable.cpp",
@@ -413,7 +407,6 @@
srcs: [
"tests/microbench/main.cpp",
"tests/microbench/DisplayListCanvasBench.cpp",
- "tests/microbench/FontBench.cpp",
"tests/microbench/FrameBuilderBench.cpp",
"tests/microbench/LinearAllocatorBench.cpp",
"tests/microbench/PathParserBench.cpp",
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index f78cb41..2c7aab8 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -187,121 +187,14 @@
static void renderTextShadow(BakedOpRenderer& renderer, const TextOp& op,
const BakedOpState& textOpState) {
- if (CC_LIKELY(!PaintUtils::hasTextShadow(op.paint))) return;
-
- FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
- fontRenderer.setFont(op.paint, SkMatrix::I());
- renderer.caches().textureState().activateTexture(0);
-
- PaintUtils::TextShadow textShadow;
- if (!PaintUtils::getTextShadow(op.paint, &textShadow)) {
- LOG_ALWAYS_FATAL("failed to query shadow attributes");
- }
-
- renderer.caches().dropShadowCache.setFontRenderer(fontRenderer);
- ShadowTexture* texture = renderer.caches().dropShadowCache.get(
- op.paint, op.glyphs, op.glyphCount, textShadow.radius, op.positions);
- // If the drop shadow exceeds the max texture size or couldn't be
- // allocated, skip drawing
- if (!texture) return;
- const AutoTexture autoCleanup(texture);
-
- const float sx = op.x - texture->left + textShadow.dx;
- const float sy = op.y - texture->top + textShadow.dy;
-
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(textOpState.roundRectClipState)
- .setMeshTexturedUnitQuad(nullptr)
- .setFillShadowTexturePaint(*texture, textShadow.color, *op.paint, textOpState.alpha)
- .setTransform(textOpState.computedState.transform, TransformFlags::None)
- .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width(), sy + texture->height()))
- .build();
-
- // Compute damage bounds and clip (since may differ from those in textOpState).
- // Bounds should be same as text op, but with dx/dy offset and radius outset
- // applied in local space.
- auto& transform = textOpState.computedState.transform;
- Rect shadowBounds = op.unmappedBounds; // STROKE
- const bool expandForStroke = op.paint->getStyle() != SkPaint::kFill_Style;
- if (expandForStroke) {
- shadowBounds.outset(op.paint->getStrokeWidth() * 0.5f);
- }
- shadowBounds.translate(textShadow.dx, textShadow.dy);
- shadowBounds.outset(textShadow.radius, textShadow.radius);
- transform.mapRect(shadowBounds);
- if (CC_UNLIKELY(expandForStroke &&
- (!transform.isPureTranslate() || op.paint->getStrokeWidth() < 1.0f))) {
- shadowBounds.outset(0.5f);
- }
-
- auto clipState = textOpState.computedState.clipState;
- if (clipState->mode != ClipMode::Rectangle || !clipState->rect.contains(shadowBounds)) {
- // need clip, so pass it and clip bounds
- shadowBounds.doIntersect(clipState->rect);
- } else {
- // don't need clip, ignore
- clipState = nullptr;
- }
-
- renderer.renderGlop(&shadowBounds, clipState, glop);
+ // DEAD CODE
}
enum class TextRenderType { Defer, Flush };
static void renderText(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state,
const ClipBase* renderClip, TextRenderType renderType) {
- FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
- float x = op.x;
- float y = op.y;
- const Matrix4& transform = state.computedState.transform;
- const bool pureTranslate = transform.isPureTranslate();
- if (CC_LIKELY(pureTranslate)) {
- x = floorf(x + transform.getTranslateX() + 0.5f);
- y = floorf(y + transform.getTranslateY() + 0.5f);
- fontRenderer.setFont(op.paint, SkMatrix::I());
- fontRenderer.setTextureFiltering(false);
- } else if (CC_UNLIKELY(transform.isPerspective())) {
- fontRenderer.setFont(op.paint, SkMatrix::I());
- fontRenderer.setTextureFiltering(true);
- } else {
- // We only pass a partial transform to the font renderer. That partial
- // matrix defines how glyphs are rasterized. Typically we want glyphs
- // to be rasterized at their final size on screen, which means the partial
- // matrix needs to take the scale factor into account.
- // When a partial matrix is used to transform glyphs during rasterization,
- // the mesh is generated with the inverse transform (in the case of scale,
- // the mesh is generated at 1.0 / scale for instance.) This allows us to
- // apply the full transform matrix at draw time in the vertex shader.
- // Applying the full matrix in the shader is the easiest way to handle
- // rotation and perspective and allows us to always generated quads in the
- // font renderer which greatly simplifies the code, clipping in particular.
- float sx, sy;
- transform.decomposeScale(sx, sy);
- fontRenderer.setFont(op.paint, SkMatrix::MakeScale(roundf(std::max(1.0f, sx)),
- roundf(std::max(1.0f, sy))));
- fontRenderer.setTextureFiltering(true);
- }
- Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
-
- int alpha = PaintUtils::getAlphaDirect(op.paint) * state.alpha;
- SkBlendMode mode = PaintUtils::getBlendModeDirect(op.paint);
- TextDrawFunctor functor(&renderer, &state, renderClip, x, y, pureTranslate, alpha, mode,
- op.paint);
-
- bool forceFinish = (renderType == TextRenderType::Flush);
- bool mustDirtyRenderTarget = renderer.offscreenRenderTarget();
- const Rect* localOpClip = pureTranslate ? &state.computedState.clipRect() : nullptr;
- fontRenderer.renderPosText(op.paint, localOpClip, op.glyphs, op.glyphCount, x, y, op.positions,
- mustDirtyRenderTarget ? &layerBounds : nullptr, &functor,
- forceFinish);
-
- if (mustDirtyRenderTarget) {
- if (!pureTranslate) {
- transform.mapRect(layerBounds);
- }
- renderer.dirtyRenderTarget(layerBounds);
- }
+ // DEAD CODE
}
void BakedOpDispatcher::onMergedTextOps(BakedOpRenderer& renderer,
@@ -747,32 +640,7 @@
void BakedOpDispatcher::onTextOnPathOp(BakedOpRenderer& renderer, const TextOnPathOp& op,
const BakedOpState& state) {
- // Note: can't trust clipSideFlags since we record with unmappedBounds == clip.
- // TODO: respect clipSideFlags, once we record with bounds
- auto renderTargetClip = state.computedState.clipState;
-
- FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer();
- fontRenderer.setFont(op.paint, SkMatrix::I());
- fontRenderer.setTextureFiltering(true);
-
- Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
-
- int alpha = PaintUtils::getAlphaDirect(op.paint) * state.alpha;
- SkBlendMode mode = PaintUtils::getBlendModeDirect(op.paint);
- TextDrawFunctor functor(&renderer, &state, renderTargetClip, 0.0f, 0.0f, false, alpha, mode,
- op.paint);
-
- bool mustDirtyRenderTarget = renderer.offscreenRenderTarget();
- const Rect localSpaceClip = state.computedState.computeLocalSpaceClip();
- if (fontRenderer.renderTextOnPath(op.paint, &localSpaceClip, op.glyphs, op.glyphCount, op.path,
- op.hOffset, op.vOffset,
- mustDirtyRenderTarget ? &layerBounds : nullptr, &functor)) {
- if (mustDirtyRenderTarget) {
- // manually dirty render target, since TextDrawFunctor won't
- state.computedState.transform.mapRect(layerBounds);
- renderer.dirtyRenderTarget(layerBounds);
- }
- }
+ // DEAD CODE
}
void BakedOpDispatcher::onTextureLayerOp(BakedOpRenderer& renderer, const TextureLayerOp& op,
diff --git a/libs/hwui/BakedOpDispatcher.h b/libs/hwui/BakedOpDispatcher.h
index e370868..cc32870 100644
--- a/libs/hwui/BakedOpDispatcher.h
+++ b/libs/hwui/BakedOpDispatcher.h
@@ -23,6 +23,8 @@
namespace android {
namespace uirenderer {
+class BakedOpRenderer;
+
/**
* Provides all "onBitmapOp(...)" style static methods for every op type, which convert the
* RecordedOps and their state to Glops, and renders them with the provided BakedOpRenderer.
diff --git a/libs/hwui/BakedOpState.h b/libs/hwui/BakedOpState.h
index c744755..e12dfbb 100644
--- a/libs/hwui/BakedOpState.h
+++ b/libs/hwui/BakedOpState.h
@@ -25,6 +25,8 @@
namespace android {
namespace uirenderer {
+class BakedOpState;
+
namespace OpClipSideFlags {
enum {
None = 0x0,
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index 3c774a3..6aefb35 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -16,14 +16,10 @@
#include "Caches.h"
-#include "GammaFontRenderer.h"
#include "GlLayer.h"
#include "Properties.h"
#include "ShadowTessellator.h"
#include "renderstate/RenderState.h"
-#ifdef BUGREPORT_FONT_CACHE_USAGE
-#include "font/FontCacheHistoryTracker.h"
-#endif
#include "utils/GLUtils.h"
#include <cutils/properties.h>
@@ -186,13 +182,9 @@
pathCache.getMaxSize());
log.appendFormat(" TessellationCache %8d / %8d\n", tessellationCache.getSize(),
tessellationCache.getMaxSize());
- log.appendFormat(" TextDropShadowCache %8d / %8d\n", dropShadowCache.getSize(),
- dropShadowCache.getMaxSize());
log.appendFormat(" PatchCache %8d / %8d\n", patchCache.getSize(),
patchCache.getMaxSize());
- fontRenderer.dumpMemoryUsage(log);
-
log.appendFormat("Other:\n");
log.appendFormat(" FboCache %8d / %8d\n", fboCache.getSize(),
fboCache.getMaxSize());
@@ -202,16 +194,10 @@
total += gradientCache.getSize();
total += pathCache.getSize();
total += tessellationCache.getSize();
- total += dropShadowCache.getSize();
total += patchCache.getSize();
- total += fontRenderer.getSize();
log.appendFormat("Total memory usage:\n");
log.appendFormat(" %d bytes, %.2f MB\n", total, total / 1024.0f / 1024.0f);
-
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- fontRenderer.getFontRenderer().historyTracker().dump(log);
-#endif
}
///////////////////////////////////////////////////////////////////////////////
@@ -230,13 +216,10 @@
case FlushMode::Full:
textureCache.clear();
patchCache.clear();
- dropShadowCache.clear();
gradientCache.clear();
- fontRenderer.clear();
fboCache.clear();
// fall through
case FlushMode::Moderate:
- fontRenderer.flush();
textureCache.flush();
pathCache.clear();
tessellationCache.clear();
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index 9732832..ed2d0b3 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -19,7 +19,6 @@
#include "DeviceInfo.h"
#include "Extensions.h"
#include "FboCache.h"
-#include "GammaFontRenderer.h"
#include "GradientCache.h"
#include "PatchCache.h"
#include "PathCache.h"
@@ -27,7 +26,6 @@
#include "RenderBufferCache.h"
#include "ResourceCache.h"
#include "TessellationCache.h"
-#include "TextDropShadowCache.h"
#include "TextureCache.h"
#include "renderstate/PixelBufferState.h"
#include "renderstate/TextureState.h"
@@ -149,11 +147,8 @@
PathCache pathCache;
ProgramCache programCache;
TessellationCache tessellationCache;
- TextDropShadowCache dropShadowCache;
FboCache fboCache;
- GammaFontRenderer fontRenderer;
-
TaskManager tasks;
bool gpuPixelBuffersEnabled;
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
index 0cfc3b7..7a9c65d 100644
--- a/libs/hwui/DisplayList.h
+++ b/libs/hwui/DisplayList.h
@@ -50,6 +50,7 @@
namespace android {
namespace uirenderer {
+struct ClipBase;
class Rect;
class Layer;
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
deleted file mode 100644
index bbcedb1..0000000
--- a/libs/hwui/FontRenderer.cpp
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
- * Copyright (C) 2010 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 "FontRenderer.h"
-
-#include "BakedOpDispatcher.h"
-#include "BakedOpRenderer.h"
-#include "BakedOpState.h"
-#include "Caches.h"
-#include "Debug.h"
-#include "Extensions.h"
-#include "Glop.h"
-#include "GlopBuilder.h"
-#include "PixelBuffer.h"
-#include "Rect.h"
-#include "font/Font.h"
-#include "renderstate/RenderState.h"
-#include "utils/Blur.h"
-#include "utils/Timing.h"
-
-#include <RenderScript.h>
-#include <SkGlyph.h>
-#include <SkUtils.h>
-#include <utils/Log.h>
-#include <algorithm>
-
-namespace android {
-namespace uirenderer {
-
-// blur inputs smaller than this constant will bypass renderscript
-#define RS_MIN_INPUT_CUTOFF 10000
-
-///////////////////////////////////////////////////////////////////////////////
-// TextSetupFunctor
-///////////////////////////////////////////////////////////////////////////////
-
-void TextDrawFunctor::draw(CacheTexture& texture, bool linearFiltering) {
- int textureFillFlags = TextureFillFlags::None;
- if (texture.getFormat() == GL_ALPHA) {
- textureFillFlags |= TextureFillFlags::IsAlphaMaskTexture;
- }
- if (linearFiltering) {
- textureFillFlags |= TextureFillFlags::ForceFilter;
- }
- int transformFlags =
- pureTranslate ? TransformFlags::MeshIgnoresCanvasTransform : TransformFlags::None;
-#ifdef ANDROID_ENABLE_LINEAR_BLENDING
- bool gammaCorrection = true;
-#else
- bool gammaCorrection = false;
-#endif
- Glop glop;
- GlopBuilder(renderer->renderState(), renderer->caches(), &glop)
- .setRoundRectClipState(bakedState->roundRectClipState)
- .setMeshTexturedIndexedQuads(texture.mesh(), texture.meshElementCount())
- .setFillTexturePaint(texture.getTexture(), textureFillFlags, paint, bakedState->alpha)
- .setGammaCorrection(gammaCorrection)
- .setTransform(bakedState->computedState.transform, transformFlags)
- .setModelViewIdentityEmptyBounds()
- .build();
- // Note: don't pass dirty bounds here, so user must manage passing dirty bounds to renderer
- renderer->renderGlop(nullptr, clip, glop);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// FontRenderer
-///////////////////////////////////////////////////////////////////////////////
-
-static bool sLogFontRendererCreate = true;
-
-FontRenderer::FontRenderer(const uint8_t* gammaTable)
- : mGammaTable(gammaTable)
- , mCurrentFont(nullptr)
- , mActiveFonts(LruCache<Font::FontDescription, Font*>::kUnlimitedCapacity)
- , mCurrentCacheTexture(nullptr)
- , mUploadTexture(false)
- , mFunctor(nullptr)
- , mClip(nullptr)
- , mBounds(nullptr)
- , mDrawn(false)
- , mInitialized(false)
- , mLinearFiltering(false) {
- if (sLogFontRendererCreate) {
- INIT_LOGD("Creating FontRenderer");
- }
-
- auto deviceInfo = DeviceInfo::get();
- auto displayInfo = deviceInfo->displayInfo();
- int maxTextureSize = deviceInfo->maxTextureSize();
-
- // Adjust cache size based on Pixel's desnsity.
- constexpr float PIXEL_DENSITY = 2.6;
- const float densityRatio = displayInfo.density / PIXEL_DENSITY;
-
- // TODO: Most devices are hardcoded with this configuration, does it need to be dynamic?
- mSmallCacheWidth =
- OffscreenBuffer::computeIdealDimension(std::min(1024, maxTextureSize) * densityRatio);
- mSmallCacheHeight =
- OffscreenBuffer::computeIdealDimension(std::min(1024, maxTextureSize) * densityRatio);
- mLargeCacheWidth =
- OffscreenBuffer::computeIdealDimension(std::min(2048, maxTextureSize) * densityRatio);
- mLargeCacheHeight =
- OffscreenBuffer::computeIdealDimension(std::min(1024, maxTextureSize) * densityRatio);
-
- if (sLogFontRendererCreate) {
- INIT_LOGD(" Text cache sizes, in pixels: %i x %i, %i x %i, %i x %i, %i x %i",
- mSmallCacheWidth, mSmallCacheHeight, mLargeCacheWidth, mLargeCacheHeight >> 1,
- mLargeCacheWidth, mLargeCacheHeight >> 1, mLargeCacheWidth, mLargeCacheHeight);
- }
-
- sLogFontRendererCreate = false;
-}
-
-void clearCacheTextures(std::vector<CacheTexture*>& cacheTextures) {
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- delete cacheTextures[i];
- }
- cacheTextures.clear();
-}
-
-FontRenderer::~FontRenderer() {
- clearCacheTextures(mACacheTextures);
- clearCacheTextures(mRGBACacheTextures);
-
- LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
- while (it.next()) {
- delete it.value();
- }
- mActiveFonts.clear();
-}
-
-void FontRenderer::flushAllAndInvalidate() {
- issueDrawCommand();
-
- LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
- while (it.next()) {
- it.value()->invalidateTextureCache();
- }
-
- for (uint32_t i = 0; i < mACacheTextures.size(); i++) {
- mACacheTextures[i]->init();
-
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- mHistoryTracker.glyphsCleared(mACacheTextures[i]);
-#endif
- }
-
- for (uint32_t i = 0; i < mRGBACacheTextures.size(); i++) {
- mRGBACacheTextures[i]->init();
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- mHistoryTracker.glyphsCleared(mRGBACacheTextures[i]);
-#endif
- }
-
- mDrawn = false;
-}
-
-void FontRenderer::flushLargeCaches(std::vector<CacheTexture*>& cacheTextures) {
- // Start from 1; don't deallocate smallest/default texture
- for (uint32_t i = 1; i < cacheTextures.size(); i++) {
- CacheTexture* cacheTexture = cacheTextures[i];
- if (cacheTexture->getPixelBuffer()) {
- cacheTexture->init();
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- mHistoryTracker.glyphsCleared(cacheTexture);
-#endif
- LruCache<Font::FontDescription, Font*>::Iterator it(mActiveFonts);
- while (it.next()) {
- it.value()->invalidateTextureCache(cacheTexture);
- }
- cacheTexture->releasePixelBuffer();
- }
- }
-}
-
-void FontRenderer::flushLargeCaches() {
- flushLargeCaches(mACacheTextures);
- flushLargeCaches(mRGBACacheTextures);
-}
-
-CacheTexture* FontRenderer::cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures,
- const SkGlyph& glyph, uint32_t* startX,
- uint32_t* startY) {
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- if (cacheTextures[i]->fitBitmap(glyph, startX, startY)) {
- return cacheTextures[i];
- }
- }
- // Could not fit glyph into current cache textures
- return nullptr;
-}
-
-void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
- uint32_t* retOriginX, uint32_t* retOriginY, bool precaching) {
- checkInit();
-
- // If the glyph bitmap is empty let's assum the glyph is valid
- // so we can avoid doing extra work later on
- if (glyph.fWidth == 0 || glyph.fHeight == 0) {
- cachedGlyph->mIsValid = true;
- cachedGlyph->mCacheTexture = nullptr;
- return;
- }
-
- cachedGlyph->mIsValid = false;
-
- // choose an appropriate cache texture list for this glyph format
- SkMask::Format format = static_cast<SkMask::Format>(glyph.fMaskFormat);
- std::vector<CacheTexture*>* cacheTextures = nullptr;
- switch (format) {
- case SkMask::kA8_Format:
- case SkMask::kBW_Format:
- cacheTextures = &mACacheTextures;
- break;
- case SkMask::kARGB32_Format:
- cacheTextures = &mRGBACacheTextures;
- break;
- default:
-#if DEBUG_FONT_RENDERER
- ALOGD("getCacheTexturesForFormat: unknown SkMask format %x", format);
-#endif
- return;
- }
-
- // If the glyph is too tall, don't cache it
- if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 >
- (*cacheTextures)[cacheTextures->size() - 1]->getHeight()) {
- ALOGE("Font size too large to fit in cache. width, height = %i, %i", (int)glyph.fWidth,
- (int)glyph.fHeight);
- return;
- }
-
- // Now copy the bitmap into the cache texture
- uint32_t startX = 0;
- uint32_t startY = 0;
-
- CacheTexture* cacheTexture = cacheBitmapInTexture(*cacheTextures, glyph, &startX, &startY);
-
- if (!cacheTexture) {
- if (!precaching) {
- // If the new glyph didn't fit and we are not just trying to precache it,
- // clear out the cache and try again
- flushAllAndInvalidate();
- cacheTexture = cacheBitmapInTexture(*cacheTextures, glyph, &startX, &startY);
- }
-
- if (!cacheTexture) {
- // either the glyph didn't fit or we're precaching and will cache it when we draw
- return;
- }
- }
-
- cachedGlyph->mCacheTexture = cacheTexture;
-
- *retOriginX = startX;
- *retOriginY = startY;
-
- uint32_t endX = startX + glyph.fWidth;
- uint32_t endY = startY + glyph.fHeight;
-
- uint32_t cacheWidth = cacheTexture->getWidth();
-
- if (!cacheTexture->getPixelBuffer()) {
- Caches::getInstance().textureState().activateTexture(0);
- // Large-glyph texture memory is allocated only as needed
- cacheTexture->allocatePixelBuffer();
- }
- if (!cacheTexture->mesh()) {
- cacheTexture->allocateMesh();
- }
-
- uint8_t* cacheBuffer = cacheTexture->getPixelBuffer()->map();
- uint8_t* bitmapBuffer = (uint8_t*)glyph.fImage;
- int srcStride = glyph.rowBytes();
-
- // Copy the glyph image, taking the mask format into account
- switch (format) {
- case SkMask::kA8_Format: {
- uint32_t row =
- (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
- // write leading border line
- memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
- // write glyph data
- if (mGammaTable) {
- for (uint32_t cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += srcStride) {
- row = cacheY * cacheWidth;
- cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
- for (uint32_t cacheX = startX, bX = 0; cacheX < endX; cacheX++, bX++) {
- uint8_t tempCol = bitmapBuffer[bY + bX];
- cacheBuffer[row + cacheX] = mGammaTable[tempCol];
- }
- cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
- }
- } else {
- for (uint32_t cacheY = startY, bY = 0; cacheY < endY; cacheY++, bY += srcStride) {
- row = cacheY * cacheWidth;
- memcpy(&cacheBuffer[row + startX], &bitmapBuffer[bY], glyph.fWidth);
- cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
- cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
- }
- }
- // write trailing border line
- row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
- memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
- break;
- }
- case SkMask::kARGB32_Format: {
- // prep data lengths
- const size_t formatSize = PixelBuffer::formatSize(GL_RGBA);
- const size_t borderSize = formatSize * TEXTURE_BORDER_SIZE;
- size_t rowSize = formatSize * glyph.fWidth;
- // prep advances
- size_t dstStride = formatSize * cacheWidth;
- // prep indices
- // - we actually start one row early, and then increment before first copy
- uint8_t* src = &bitmapBuffer[0 - srcStride];
- uint8_t* dst = &cacheBuffer[cacheTexture->getOffset(startX, startY - 1)];
- uint8_t* dstEnd = &cacheBuffer[cacheTexture->getOffset(startX, endY - 1)];
- uint8_t* dstL = dst - borderSize;
- uint8_t* dstR = dst + rowSize;
- // write leading border line
- memset(dstL, 0, rowSize + 2 * borderSize);
- // write glyph data
- while (dst < dstEnd) {
- memset(dstL += dstStride, 0, borderSize); // leading border column
- memcpy(dst += dstStride, src += srcStride, rowSize); // glyph data
- memset(dstR += dstStride, 0, borderSize); // trailing border column
- }
- // write trailing border line
- memset(dstL += dstStride, 0, rowSize + 2 * borderSize);
- break;
- }
- case SkMask::kBW_Format: {
- uint32_t cacheX = 0, cacheY = 0;
- uint32_t row =
- (startY - TEXTURE_BORDER_SIZE) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
- static const uint8_t COLORS[2] = {0, 255};
- // write leading border line
- memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
- // write glyph data
- for (cacheY = startY; cacheY < endY; cacheY++) {
- cacheX = startX;
- int rowBytes = srcStride;
- uint8_t* buffer = bitmapBuffer;
-
- row = cacheY * cacheWidth;
- cacheBuffer[row + startX - TEXTURE_BORDER_SIZE] = 0;
- while (--rowBytes >= 0) {
- uint8_t b = *buffer++;
- for (int8_t mask = 7; mask >= 0 && cacheX < endX; mask--) {
- cacheBuffer[cacheY * cacheWidth + cacheX++] = COLORS[(b >> mask) & 0x1];
- }
- }
- cacheBuffer[row + endX + TEXTURE_BORDER_SIZE - 1] = 0;
-
- bitmapBuffer += srcStride;
- }
- // write trailing border line
- row = (endY + TEXTURE_BORDER_SIZE - 1) * cacheWidth + startX - TEXTURE_BORDER_SIZE;
- memset(&cacheBuffer[row], 0, glyph.fWidth + 2 * TEXTURE_BORDER_SIZE);
- break;
- }
- default:
- ALOGW("Unknown glyph format: 0x%x", format);
- break;
- }
-
- cachedGlyph->mIsValid = true;
-
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- mHistoryTracker.glyphUploaded(cacheTexture, startX, startY, glyph.fWidth, glyph.fHeight);
-#endif
-}
-
-CacheTexture* FontRenderer::createCacheTexture(int width, int height, GLenum format,
- bool allocate) {
- CacheTexture* cacheTexture = new CacheTexture(width, height, format, kMaxNumberOfQuads);
-
- if (allocate) {
- Caches::getInstance().textureState().activateTexture(0);
- cacheTexture->allocatePixelBuffer();
- cacheTexture->allocateMesh();
- }
-
- return cacheTexture;
-}
-
-void FontRenderer::initTextTexture() {
- clearCacheTextures(mACacheTextures);
- clearCacheTextures(mRGBACacheTextures);
-
- mUploadTexture = false;
- mACacheTextures.push_back(
- createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, GL_ALPHA, true));
- mACacheTextures.push_back(
- createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_ALPHA, false));
- mACacheTextures.push_back(
- createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_ALPHA, false));
- mACacheTextures.push_back(
- createCacheTexture(mLargeCacheWidth, mLargeCacheHeight, GL_ALPHA, false));
- mRGBACacheTextures.push_back(
- createCacheTexture(mSmallCacheWidth, mSmallCacheHeight, GL_RGBA, false));
- mRGBACacheTextures.push_back(
- createCacheTexture(mLargeCacheWidth, mLargeCacheHeight >> 1, GL_RGBA, false));
- mCurrentCacheTexture = mACacheTextures[0];
-}
-
-// We don't want to allocate anything unless we actually draw text
-void FontRenderer::checkInit() {
- if (mInitialized) {
- return;
- }
-
- initTextTexture();
-
- mInitialized = true;
-}
-
-void checkTextureUpdateForCache(Caches& caches, std::vector<CacheTexture*>& cacheTextures,
- bool& resetPixelStore, GLuint& lastTextureId) {
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- CacheTexture* cacheTexture = cacheTextures[i];
- if (cacheTexture->isDirty() && cacheTexture->getPixelBuffer()) {
- if (cacheTexture->getTextureId() != lastTextureId) {
- lastTextureId = cacheTexture->getTextureId();
- caches.textureState().activateTexture(0);
- caches.textureState().bindTexture(lastTextureId);
- }
-
- if (cacheTexture->upload()) {
- resetPixelStore = true;
- }
- }
- }
-}
-
-void FontRenderer::checkTextureUpdate() {
- if (!mUploadTexture) {
- return;
- }
-
- Caches& caches = Caches::getInstance();
- GLuint lastTextureId = 0;
-
- bool resetPixelStore = false;
-
- // Iterate over all the cache textures and see which ones need to be updated
- checkTextureUpdateForCache(caches, mACacheTextures, resetPixelStore, lastTextureId);
- checkTextureUpdateForCache(caches, mRGBACacheTextures, resetPixelStore, lastTextureId);
-
- // Unbind any PBO we might have used to update textures
- caches.pixelBufferState().unbind();
-
- // Reset to default unpack row length to avoid affecting texture
- // uploads in other parts of the renderer
- if (resetPixelStore) {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
- }
-
- mUploadTexture = false;
-}
-
-void FontRenderer::issueDrawCommand(std::vector<CacheTexture*>& cacheTextures) {
- if (!mFunctor) return;
-
- bool first = true;
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- CacheTexture* texture = cacheTextures[i];
- if (texture->canDraw()) {
- if (first) {
- checkTextureUpdate();
- first = false;
- mDrawn = true;
- }
-
- mFunctor->draw(*texture, mLinearFiltering);
-
- texture->resetMesh();
- }
- }
-}
-
-void FontRenderer::issueDrawCommand() {
- issueDrawCommand(mACacheTextures);
- issueDrawCommand(mRGBACacheTextures);
-}
-
-void FontRenderer::appendMeshQuadNoClip(float x1, float y1, float u1, float v1, float x2, float y2,
- float u2, float v2, float x3, float y3, float u3, float v3,
- float x4, float y4, float u4, float v4,
- CacheTexture* texture) {
- if (texture != mCurrentCacheTexture) {
- // Now use the new texture id
- mCurrentCacheTexture = texture;
- }
-
- mCurrentCacheTexture->addQuad(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4);
-}
-
-void FontRenderer::appendMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2,
- float u2, float v2, float x3, float y3, float u3, float v3,
- float x4, float y4, float u4, float v4, CacheTexture* texture) {
- if (mClip && (x1 > mClip->right || y1 < mClip->top || x2 < mClip->left || y4 > mClip->bottom)) {
- return;
- }
-
- appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);
-
- if (mBounds) {
- mBounds->left = std::min(mBounds->left, x1);
- mBounds->top = std::min(mBounds->top, y3);
- mBounds->right = std::max(mBounds->right, x3);
- mBounds->bottom = std::max(mBounds->bottom, y1);
- }
-
- if (mCurrentCacheTexture->endOfMesh()) {
- issueDrawCommand();
- }
-}
-
-void FontRenderer::appendRotatedMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2,
- float u2, float v2, float x3, float y3, float u3, float v3,
- float x4, float y4, float u4, float v4,
- CacheTexture* texture) {
- appendMeshQuadNoClip(x1, y1, u1, v1, x2, y2, u2, v2, x3, y3, u3, v3, x4, y4, u4, v4, texture);
-
- if (mBounds) {
- mBounds->left = std::min(mBounds->left, std::min(x1, std::min(x2, std::min(x3, x4))));
- mBounds->top = std::min(mBounds->top, std::min(y1, std::min(y2, std::min(y3, y4))));
- mBounds->right = std::max(mBounds->right, std::max(x1, std::max(x2, std::max(x3, x4))));
- mBounds->bottom = std::max(mBounds->bottom, std::max(y1, std::max(y2, std::max(y3, y4))));
- }
-
- if (mCurrentCacheTexture->endOfMesh()) {
- issueDrawCommand();
- }
-}
-
-void FontRenderer::setFont(const SkPaint* paint, const SkMatrix& matrix) {
- mCurrentFont = Font::create(this, paint, matrix);
-}
-
-FontRenderer::DropShadow FontRenderer::renderDropShadow(const SkPaint* paint, const glyph_t* glyphs,
- int numGlyphs, float radius,
- const float* positions) {
- checkInit();
-
- DropShadow image;
- image.width = 0;
- image.height = 0;
- image.image = nullptr;
- image.penX = 0;
- image.penY = 0;
-
- if (!mCurrentFont) {
- return image;
- }
-
- mDrawn = false;
- mClip = nullptr;
- mBounds = nullptr;
-
- Rect bounds;
- mCurrentFont->measure(paint, glyphs, numGlyphs, &bounds, positions);
-
- uint32_t intRadius = Blur::convertRadiusToInt(radius);
- uint32_t paddedWidth = (uint32_t)(bounds.right - bounds.left) + 2 * intRadius;
- uint32_t paddedHeight = (uint32_t)(bounds.top - bounds.bottom) + 2 * intRadius;
-
- uint32_t maxSize = Caches::getInstance().maxTextureSize;
- if (paddedWidth > maxSize || paddedHeight > maxSize) {
- return image;
- }
-
- // Align buffers for renderscript usage
- if (paddedWidth & (RS_CPU_ALLOCATION_ALIGNMENT - 1)) {
- paddedWidth += RS_CPU_ALLOCATION_ALIGNMENT - paddedWidth % RS_CPU_ALLOCATION_ALIGNMENT;
- }
- int size = paddedWidth * paddedHeight;
- uint8_t* dataBuffer = (uint8_t*)memalign(RS_CPU_ALLOCATION_ALIGNMENT, size);
-
- memset(dataBuffer, 0, size);
-
- int penX = intRadius - bounds.left;
- int penY = intRadius - bounds.bottom;
-
- if ((bounds.right > bounds.left) && (bounds.top > bounds.bottom)) {
- // text has non-whitespace, so draw and blur to create the shadow
- // NOTE: bounds.isEmpty() can't be used here, since vertical coordinates are inverted
- // TODO: don't draw pure whitespace in the first place, and avoid needing this check
- mCurrentFont->render(paint, glyphs, numGlyphs, penX, penY, Font::BITMAP, dataBuffer,
- paddedWidth, paddedHeight, nullptr, positions);
-
- // Unbind any PBO we might have used
- Caches::getInstance().pixelBufferState().unbind();
-
- blurImage(&dataBuffer, paddedWidth, paddedHeight, radius);
- }
-
- image.width = paddedWidth;
- image.height = paddedHeight;
- image.image = dataBuffer;
- image.penX = penX;
- image.penY = penY;
-
- return image;
-}
-
-void FontRenderer::initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor) {
- checkInit();
-
- mDrawn = false;
- mBounds = bounds;
- mFunctor = functor;
- mClip = clip;
-}
-
-void FontRenderer::finishRender() {
- mBounds = nullptr;
- mClip = nullptr;
-
- issueDrawCommand();
-}
-
-void FontRenderer::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
- const SkMatrix& matrix) {
- Font* font = Font::create(this, paint, matrix);
- font->precache(paint, glyphs, numGlyphs);
-}
-
-void FontRenderer::endPrecaching() {
- checkTextureUpdate();
-}
-
-bool FontRenderer::renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
- int numGlyphs, int x, int y, const float* positions, Rect* bounds,
- TextDrawFunctor* functor, bool forceFinish) {
- if (!mCurrentFont) {
- ALOGE("No font set");
- return false;
- }
-
- initRender(clip, bounds, functor);
- mCurrentFont->render(paint, glyphs, numGlyphs, x, y, positions);
-
- if (forceFinish) {
- finishRender();
- }
-
- return mDrawn;
-}
-
-bool FontRenderer::renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
- int numGlyphs, const SkPath* path, float hOffset, float vOffset,
- Rect* bounds, TextDrawFunctor* functor) {
- if (!mCurrentFont) {
- ALOGE("No font set");
- return false;
- }
-
- initRender(clip, bounds, functor);
- mCurrentFont->render(paint, glyphs, numGlyphs, path, hOffset, vOffset);
- finishRender();
-
- return mDrawn;
-}
-
-void FontRenderer::blurImage(uint8_t** image, int32_t width, int32_t height, float radius) {
- uint32_t intRadius = Blur::convertRadiusToInt(radius);
- if (width * height * intRadius >= RS_MIN_INPUT_CUTOFF && radius <= 25.0f) {
- uint8_t* outImage = (uint8_t*)memalign(RS_CPU_ALLOCATION_ALIGNMENT, width * height);
-
- if (mRs == nullptr) {
- mRs = new RSC::RS();
- // a null path is OK because there are no custom kernels used
- // hence nothing gets cached by RS
- if (!mRs->init("", RSC::RS_INIT_LOW_LATENCY | RSC::RS_INIT_SYNCHRONOUS)) {
- mRs.clear();
- ALOGE("blur RS failed to init");
- } else {
- mRsElement = RSC::Element::A_8(mRs);
- mRsScript = RSC::ScriptIntrinsicBlur::create(mRs, mRsElement);
- }
- }
- if (mRs != nullptr) {
- RSC::sp<const RSC::Type> t = RSC::Type::create(mRs, mRsElement, width, height, 0);
- RSC::sp<RSC::Allocation> ain = RSC::Allocation::createTyped(
- mRs, t, RS_ALLOCATION_MIPMAP_NONE,
- RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED, *image);
- RSC::sp<RSC::Allocation> aout = RSC::Allocation::createTyped(
- mRs, t, RS_ALLOCATION_MIPMAP_NONE,
- RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED, outImage);
-
- mRsScript->setRadius(radius);
- mRsScript->setInput(ain);
- mRsScript->forEach(aout);
-
- // replace the original image's pointer, avoiding a copy back to the original buffer
- free(*image);
- *image = outImage;
-
- return;
- }
- }
-
- std::unique_ptr<float[]> gaussian(new float[2 * intRadius + 1]);
- Blur::generateGaussianWeights(gaussian.get(), radius);
-
- std::unique_ptr<uint8_t[]> scratch(new uint8_t[width * height]);
- Blur::horizontal(gaussian.get(), intRadius, *image, scratch.get(), width, height);
- Blur::vertical(gaussian.get(), intRadius, scratch.get(), *image, width, height);
-}
-
-static uint32_t calculateCacheSize(const std::vector<CacheTexture*>& cacheTextures) {
- uint32_t size = 0;
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- CacheTexture* cacheTexture = cacheTextures[i];
- if (cacheTexture && cacheTexture->getPixelBuffer()) {
- size += cacheTexture->getPixelBuffer()->getSize();
- }
- }
- return size;
-}
-
-static uint32_t calculateFreeCacheSize(const std::vector<CacheTexture*>& cacheTextures) {
- uint32_t size = 0;
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- CacheTexture* cacheTexture = cacheTextures[i];
- if (cacheTexture && cacheTexture->getPixelBuffer()) {
- size += cacheTexture->calculateFreeMemory();
- }
- }
- return size;
-}
-
-const std::vector<CacheTexture*>& FontRenderer::cacheTexturesForFormat(GLenum format) const {
- switch (format) {
- case GL_ALPHA: {
- return mACacheTextures;
- }
- case GL_RGBA: {
- return mRGBACacheTextures;
- }
- default: {
- LOG_ALWAYS_FATAL("Unsupported format: %d", format);
- // Impossible to hit this, but the compiler doesn't know that
- return *(new std::vector<CacheTexture*>());
- }
- }
-}
-
-static void dumpTextures(String8& log, const char* tag,
- const std::vector<CacheTexture*>& cacheTextures) {
- for (uint32_t i = 0; i < cacheTextures.size(); i++) {
- CacheTexture* cacheTexture = cacheTextures[i];
- if (cacheTexture && cacheTexture->getPixelBuffer()) {
- uint32_t free = cacheTexture->calculateFreeMemory();
- uint32_t total = cacheTexture->getPixelBuffer()->getSize();
- log.appendFormat(" %-4s texture %d %8d / %8d\n", tag, i, total - free, total);
- }
- }
-}
-
-void FontRenderer::dumpMemoryUsage(String8& log) const {
- const uint32_t sizeA8 = getCacheSize(GL_ALPHA);
- const uint32_t usedA8 = sizeA8 - getFreeCacheSize(GL_ALPHA);
- const uint32_t sizeRGBA = getCacheSize(GL_RGBA);
- const uint32_t usedRGBA = sizeRGBA - getFreeCacheSize(GL_RGBA);
- log.appendFormat(" FontRenderer A8 %8d / %8d\n", usedA8, sizeA8);
- dumpTextures(log, "A8", cacheTexturesForFormat(GL_ALPHA));
- log.appendFormat(" FontRenderer RGBA %8d / %8d\n", usedRGBA, sizeRGBA);
- dumpTextures(log, "RGBA", cacheTexturesForFormat(GL_RGBA));
- log.appendFormat(" FontRenderer total %8d / %8d\n", usedA8 + usedRGBA, sizeA8 + sizeRGBA);
-}
-
-uint32_t FontRenderer::getCacheSize(GLenum format) const {
- return calculateCacheSize(cacheTexturesForFormat(format));
-}
-
-uint32_t FontRenderer::getFreeCacheSize(GLenum format) const {
- return calculateFreeCacheSize(cacheTexturesForFormat(format));
-}
-
-uint32_t FontRenderer::getSize() const {
- return getCacheSize(GL_ALPHA) + getCacheSize(GL_RGBA);
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/FontRenderer.h b/libs/hwui/FontRenderer.h
deleted file mode 100644
index 6b9dec4..0000000
--- a/libs/hwui/FontRenderer.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#pragma once
-
-#include "font/CacheTexture.h"
-#include "font/CachedGlyphInfo.h"
-#include "font/Font.h"
-#include "font/FontUtil.h"
-#ifdef BUGREPORT_FONT_CACHE_USAGE
-#include "font/FontCacheHistoryTracker.h"
-#endif
-
-#include <utils/LruCache.h>
-#include <utils/String8.h>
-#include <utils/StrongPointer.h>
-
-#include <SkPaint.h>
-
-#include <GLES2/gl2.h>
-
-#include <vector>
-
-#include "RenderScript.h"
-namespace RSC {
-class Element;
-class RS;
-class ScriptIntrinsicBlur;
-class sp;
-}
-
-namespace android {
-namespace uirenderer {
-
-class BakedOpState;
-class BakedOpRenderer;
-struct ClipBase;
-
-class TextDrawFunctor {
-public:
- TextDrawFunctor(BakedOpRenderer* renderer, const BakedOpState* bakedState, const ClipBase* clip,
- float x, float y, bool pureTranslate, int alpha, SkBlendMode mode,
- const SkPaint* paint)
- : renderer(renderer)
- , bakedState(bakedState)
- , clip(clip)
- , x(x)
- , y(y)
- , pureTranslate(pureTranslate)
- , alpha(alpha)
- , mode(mode)
- , paint(paint) {}
-
- void draw(CacheTexture& texture, bool linearFiltering);
-
- BakedOpRenderer* renderer;
- const BakedOpState* bakedState;
- const ClipBase* clip;
- float x;
- float y;
- bool pureTranslate;
- int alpha;
- SkBlendMode mode;
- const SkPaint* paint;
-};
-
-class FontRenderer {
-public:
- explicit FontRenderer(const uint8_t* gammaTable);
- ~FontRenderer();
-
- void flushLargeCaches(std::vector<CacheTexture*>& cacheTextures);
- void flushLargeCaches();
-
- void setFont(const SkPaint* paint, const SkMatrix& matrix);
-
- void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
- const SkMatrix& matrix);
- void endPrecaching();
-
- bool renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs,
- int x, int y, const float* positions, Rect* outBounds,
- TextDrawFunctor* functor, bool forceFinish = true);
-
- bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
- int numGlyphs, const SkPath* path, float hOffset, float vOffset,
- Rect* outBounds, TextDrawFunctor* functor);
-
- struct DropShadow {
- uint32_t width;
- uint32_t height;
- uint8_t* image;
- int32_t penX;
- int32_t penY;
- };
-
- // After renderDropShadow returns, the called owns the memory in DropShadow.image
- // and is responsible for releasing it when it's done with it
- DropShadow renderDropShadow(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
- float radius, const float* positions);
-
- void setTextureFiltering(bool linearFiltering) { mLinearFiltering = linearFiltering; }
-
- uint32_t getSize() const;
- void dumpMemoryUsage(String8& log) const;
-
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- FontCacheHistoryTracker& historyTracker() { return mHistoryTracker; }
-#endif
-
-private:
- friend class Font;
-
- const uint8_t* mGammaTable;
-
- void allocateTextureMemory(CacheTexture* cacheTexture);
- void deallocateTextureMemory(CacheTexture* cacheTexture);
- void initTextTexture();
- CacheTexture* createCacheTexture(int width, int height, GLenum format, bool allocate);
- void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph, uint32_t* retOriginX,
- uint32_t* retOriginY, bool precaching);
- CacheTexture* cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures,
- const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);
-
- void flushAllAndInvalidate();
-
- void checkInit();
- void initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor);
- void finishRender();
-
- void issueDrawCommand(std::vector<CacheTexture*>& cacheTextures);
- void issueDrawCommand();
- void appendMeshQuadNoClip(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
- float v2, float x3, float y3, float u3, float v3, float x4, float y4,
- float u4, float v4, CacheTexture* texture);
- void appendMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
- float v2, float x3, float y3, float u3, float v3, float x4, float y4,
- float u4, float v4, CacheTexture* texture);
- void appendRotatedMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
- float v2, float x3, float y3, float u3, float v3, float x4, float y4,
- float u4, float v4, CacheTexture* texture);
-
- void checkTextureUpdate();
-
- void setTextureDirty() { mUploadTexture = true; }
-
- const std::vector<CacheTexture*>& cacheTexturesForFormat(GLenum format) const;
- uint32_t getCacheSize(GLenum format) const;
- uint32_t getFreeCacheSize(GLenum format) const;
-
- uint32_t mSmallCacheWidth;
- uint32_t mSmallCacheHeight;
- uint32_t mLargeCacheWidth;
- uint32_t mLargeCacheHeight;
-
- std::vector<CacheTexture*> mACacheTextures;
- std::vector<CacheTexture*> mRGBACacheTextures;
-
- Font* mCurrentFont;
- LruCache<Font::FontDescription, Font*> mActiveFonts;
-
- CacheTexture* mCurrentCacheTexture;
-
- bool mUploadTexture;
-
- TextDrawFunctor* mFunctor;
- const Rect* mClip;
- Rect* mBounds;
- bool mDrawn;
-
- bool mInitialized;
-
- bool mLinearFiltering;
-
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- FontCacheHistoryTracker mHistoryTracker;
-#endif
-
- // RS constructs
- RSC::sp<RSC::RS> mRs;
- RSC::sp<const RSC::Element> mRsElement;
- RSC::sp<RSC::ScriptIntrinsicBlur> mRsScript;
-
- static void computeGaussianWeights(float* weights, int32_t radius);
- static void horizontalBlur(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest,
- int32_t width, int32_t height);
- static void verticalBlur(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest,
- int32_t width, int32_t height);
-
- // the input image handle may have its pointer replaced (to avoid copies)
- void blurImage(uint8_t** image, int32_t width, int32_t height, float radius);
-};
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index ced37ed..049cd45 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -722,48 +722,12 @@
currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
}
-static batchid_t textBatchId(const SkPaint& paint) {
- // TODO: better handling of shader (since we won't care about color then)
- return paint.getColor() == SK_ColorBLACK ? OpBatchType::Text : OpBatchType::ColorText;
-}
-
void FrameBuilder::deferTextOp(const TextOp& op) {
- BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct(
- mAllocator, *mCanvasState.writableSnapshot(), op,
- BakedOpState::StrokeBehavior::StyleDefined, false);
- if (!bakedState) return; // quick rejected
-
- batchid_t batchId = textBatchId(*(op.paint));
- if (bakedState->computedState.transform.isPureTranslate() &&
- PaintUtils::getBlendModeDirect(op.paint) == SkBlendMode::kSrcOver &&
- hasMergeableClip(*bakedState)) {
- mergeid_t mergeId = reinterpret_cast<mergeid_t>(op.paint->getColor());
- currentLayer().deferMergeableOp(mAllocator, bakedState, batchId, mergeId);
- } else {
- currentLayer().deferUnmergeableOp(mAllocator, bakedState, batchId);
- }
-
- FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer();
- auto& totalTransform = bakedState->computedState.transform;
- if (totalTransform.isPureTranslate() || totalTransform.isPerspective()) {
- fontRenderer.precache(op.paint, op.glyphs, op.glyphCount, SkMatrix::I());
- } else {
- // Partial transform case, see BakedOpDispatcher::renderTextOp
- float sx, sy;
- totalTransform.decomposeScale(sx, sy);
- fontRenderer.precache(
- op.paint, op.glyphs, op.glyphCount,
- SkMatrix::MakeScale(roundf(std::max(1.0f, sx)), roundf(std::max(1.0f, sy))));
- }
+ // DEAD CODE
}
void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) {
- BakedOpState* bakedState = tryBakeUnboundedOpState(op);
- if (!bakedState) return; // quick rejected
- currentLayer().deferUnmergeableOp(mAllocator, bakedState, textBatchId(*(op.paint)));
-
- mCaches.fontRenderer.getFontRenderer().precache(op.paint, op.glyphs, op.glyphCount,
- SkMatrix::I());
+ // DEAD CODE
}
void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) {
@@ -969,7 +933,7 @@
}
void FrameBuilder::finishDefer() {
- mCaches.fontRenderer.endPrecaching();
+ // DEAD CODE
}
} // namespace uirenderer
diff --git a/libs/hwui/GammaFontRenderer.cpp b/libs/hwui/GammaFontRenderer.cpp
deleted file mode 100644
index 88fb162..0000000
--- a/libs/hwui/GammaFontRenderer.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 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 "GammaFontRenderer.h"
-#include "Debug.h"
-#include "Properties.h"
-
-namespace android {
-namespace uirenderer {
-
-GammaFontRenderer::GammaFontRenderer() {
- INIT_LOGD("Creating lookup gamma font renderer");
-
-#ifndef ANDROID_ENABLE_LINEAR_BLENDING
- // Compute the gamma tables
- const float gamma = 1.0f / Properties::textGamma;
- for (uint32_t i = 0; i <= 255; i++) {
- mGammaTable[i] = uint8_t((float)::floor(pow(i / 255.0f, gamma) * 255.0f + 0.5f));
- }
-#endif
-}
-
-void GammaFontRenderer::endPrecaching() {
- if (mRenderer) {
- mRenderer->endPrecaching();
- }
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/GammaFontRenderer.h b/libs/hwui/GammaFontRenderer.h
deleted file mode 100644
index e900244..0000000
--- a/libs/hwui/GammaFontRenderer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef ANDROID_HWUI_GAMMA_FONT_RENDERER_H
-#define ANDROID_HWUI_GAMMA_FONT_RENDERER_H
-
-#include "FontRenderer.h"
-
-namespace android {
-namespace uirenderer {
-
-class GammaFontRenderer {
-public:
- GammaFontRenderer();
-
- void clear() { mRenderer.reset(nullptr); }
-
- void flush() {
- if (mRenderer) {
- mRenderer->flushLargeCaches();
- }
- }
-
- FontRenderer& getFontRenderer() {
- if (!mRenderer) {
- const uint8_t* table = nullptr;
-#ifndef ANDROID_ENABLE_LINEAR_BLENDING
- table = &mGammaTable[0];
-#endif
- mRenderer.reset(new FontRenderer(table));
- }
- return *mRenderer;
- }
-
- void dumpMemoryUsage(String8& log) const {
- if (mRenderer) {
- mRenderer->dumpMemoryUsage(log);
- } else {
- log.appendFormat("FontRenderer doesn't exist.\n");
- }
- }
-
- uint32_t getSize() const { return mRenderer ? mRenderer->getSize() : 0; }
-
- void endPrecaching();
-
-private:
- std::unique_ptr<FontRenderer> mRenderer;
-#ifndef ANDROID_ENABLE_LINEAR_BLENDING
- uint8_t mGammaTable[256];
-#endif
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_GAMMA_FONT_RENDERER_H
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 2f107a0..941373d 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -381,24 +381,7 @@
GlopBuilder& GlopBuilder::setFillShadowTexturePaint(ShadowTexture& texture, int shadowColor,
const SkPaint& paint, float alphaScale) {
- TRIGGER_STAGE(kFillStage);
- REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
-
- // specify invalid filter/clamp, since these are always static for ShadowTextures
- mOutGlop->fill.texture = {&texture, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr};
-
- const int ALPHA_BITMASK = SK_ColorBLACK;
- const int COLOR_BITMASK = ~ALPHA_BITMASK;
- if ((shadowColor & ALPHA_BITMASK) == ALPHA_BITMASK) {
- // shadow color is fully opaque: override its alpha with that of paint
- shadowColor &= paint.getColor() | COLOR_BITMASK;
- }
-
- setFill(shadowColor, alphaScale, paint.getBlendMode(), Blend::ModeOrderSwap::NoSwap,
- paint.getShader(), paint.getColorFilter());
-
- mDescription.hasAlpha8Texture = true;
- mDescription.modulate = mOutGlop->fill.color.isNotBlack();
+ // DEAD CODE
return *this;
}
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 2d0185a..f514691 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -22,7 +22,6 @@
#include "RenderNode.h"
#include "TessellationCache.h"
#include "Vector.h"
-#include "font/FontUtil.h"
#include "utils/LinearAllocator.h"
#include "utils/PaintUtils.h"
@@ -38,6 +37,7 @@
class OffscreenBuffer;
class RenderNode;
class DeferredLayerUpdater;
+typedef uint16_t glyph_t;
struct Vertex;
diff --git a/libs/hwui/TextDropShadowCache.cpp b/libs/hwui/TextDropShadowCache.cpp
deleted file mode 100644
index c892ceb..0000000
--- a/libs/hwui/TextDropShadowCache.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2010 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 <utils/JenkinsHash.h>
-
-#include "Caches.h"
-#include "Debug.h"
-#include "FontRenderer.h"
-#include "Properties.h"
-#include "TextDropShadowCache.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Cache support
-///////////////////////////////////////////////////////////////////////////////
-
-hash_t ShadowText::hash() const {
- uint32_t hash = JenkinsHashMix(0, glyphCount);
- hash = JenkinsHashMix(hash, android::hash_type(radius));
- hash = JenkinsHashMix(hash, android::hash_type(textSize));
- hash = JenkinsHashMix(hash, android::hash_type(typeface));
- hash = JenkinsHashMix(hash, flags);
- hash = JenkinsHashMix(hash, android::hash_type(italicStyle));
- hash = JenkinsHashMix(hash, android::hash_type(scaleX));
- if (glyphs) {
- hash = JenkinsHashMixShorts(hash, reinterpret_cast<const uint16_t*>(glyphs), glyphCount);
- }
- if (positions) {
- for (uint32_t i = 0; i < glyphCount * 2; i++) {
- hash = JenkinsHashMix(hash, android::hash_type(positions[i]));
- }
- }
- return JenkinsHashWhiten(hash);
-}
-
-int ShadowText::compare(const ShadowText& lhs, const ShadowText& rhs) {
- int deltaInt = int(lhs.glyphCount) - int(rhs.glyphCount);
- if (deltaInt != 0) return deltaInt;
-
- deltaInt = lhs.flags - rhs.flags;
- if (deltaInt != 0) return deltaInt;
-
- if (lhs.radius < rhs.radius) return -1;
- if (lhs.radius > rhs.radius) return +1;
-
- if (lhs.typeface < rhs.typeface) return -1;
- if (lhs.typeface > rhs.typeface) return +1;
-
- if (lhs.textSize < rhs.textSize) return -1;
- if (lhs.textSize > rhs.textSize) return +1;
-
- if (lhs.italicStyle < rhs.italicStyle) return -1;
- if (lhs.italicStyle > rhs.italicStyle) return +1;
-
- if (lhs.scaleX < rhs.scaleX) return -1;
- if (lhs.scaleX > rhs.scaleX) return +1;
-
- if (lhs.glyphs != rhs.glyphs) {
- if (!lhs.glyphs) return -1;
- if (!rhs.glyphs) return +1;
-
- deltaInt = memcmp(lhs.glyphs, rhs.glyphs, lhs.glyphCount * sizeof(glyph_t));
- if (deltaInt != 0) return deltaInt;
- }
-
- if (lhs.positions != rhs.positions) {
- if (!lhs.positions) return -1;
- if (!rhs.positions) return +1;
-
- return memcmp(lhs.positions, rhs.positions, lhs.glyphCount * sizeof(float) * 2);
- }
-
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
-///////////////////////////////////////////////////////////////////////////////
-
-TextDropShadowCache::TextDropShadowCache()
- : TextDropShadowCache(DeviceInfo::multiplyByResolution(2)) {}
-
-TextDropShadowCache::TextDropShadowCache(uint32_t maxByteSize)
- : mCache(LruCache<ShadowText, ShadowTexture*>::kUnlimitedCapacity)
- , mSize(0)
- , mMaxSize(maxByteSize) {
- mCache.setOnEntryRemovedListener(this);
- mDebugEnabled = Properties::debugLevel & kDebugMoreCaches;
-}
-
-TextDropShadowCache::~TextDropShadowCache() {
- mCache.clear();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t TextDropShadowCache::getSize() {
- return mSize;
-}
-
-uint32_t TextDropShadowCache::getMaxSize() {
- return mMaxSize;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void TextDropShadowCache::operator()(ShadowText&, ShadowTexture*& texture) {
- if (texture) {
- mSize -= texture->objectSize();
-
- if (mDebugEnabled) {
- ALOGD("Shadow texture deleted, size = %d", texture->bitmapSize);
- }
-
- texture->deleteTexture();
- delete texture;
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void TextDropShadowCache::clear() {
- mCache.clear();
-}
-
-ShadowTexture* TextDropShadowCache::get(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
- float radius, const float* positions) {
- ShadowText entry(paint, radius, numGlyphs, glyphs, positions);
- ShadowTexture* texture = mCache.get(entry);
-
- if (!texture) {
- SkPaint paintCopy(*paint);
- paintCopy.setTextAlign(SkPaint::kLeft_Align);
- FontRenderer::DropShadow shadow =
- mRenderer->renderDropShadow(&paintCopy, glyphs, numGlyphs, radius, positions);
-
- if (!shadow.image) {
- return nullptr;
- }
-
- Caches& caches = Caches::getInstance();
-
- texture = new ShadowTexture(caches);
- texture->left = shadow.penX;
- texture->top = shadow.penY;
- texture->generation = 0;
- texture->blend = true;
-
- const uint32_t size = shadow.width * shadow.height;
-
- // Don't even try to cache a bitmap that's bigger than the cache
- if (size < mMaxSize) {
- while (mSize + size > mMaxSize) {
- LOG_ALWAYS_FATAL_IF(!mCache.removeOldest(),
- "Failed to remove oldest from cache. mSize = %" PRIu32
- ", mCache.size() = %zu",
- mSize, mCache.size());
- }
- }
-
- // Textures are Alpha8
- texture->upload(GL_ALPHA, shadow.width, shadow.height, GL_ALPHA, GL_UNSIGNED_BYTE,
- shadow.image);
- texture->setFilter(GL_LINEAR);
- texture->setWrap(GL_CLAMP_TO_EDGE);
-
- if (size < mMaxSize) {
- if (mDebugEnabled) {
- ALOGD("Shadow texture created, size = %d", texture->bitmapSize);
- }
-
- entry.copyTextLocally();
-
- mSize += texture->objectSize();
- mCache.put(entry, texture);
- } else {
- texture->cleanup = true;
- }
-
- // Cleanup shadow
- free(shadow.image);
- }
-
- return texture;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/TextDropShadowCache.h b/libs/hwui/TextDropShadowCache.h
deleted file mode 100644
index 86a0129..0000000
--- a/libs/hwui/TextDropShadowCache.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#ifndef ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
-#define ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
-
-#include <GLES2/gl2.h>
-
-#include <SkPaint.h>
-
-#include <utils/LruCache.h>
-#include <utils/String16.h>
-
-#include "Texture.h"
-#include "font/Font.h"
-
-namespace android {
-namespace uirenderer {
-
-class Caches;
-class FontRenderer;
-
-struct ShadowText {
- ShadowText()
- : glyphCount(0)
- , radius(0.0f)
- , textSize(0.0f)
- , typeface(nullptr)
- , flags(0)
- , italicStyle(0.0f)
- , scaleX(0)
- , glyphs(nullptr)
- , positions(nullptr) {}
-
- // len is the number of bytes in text
- ShadowText(const SkPaint* paint, float radius, uint32_t glyphCount, const glyph_t* srcGlyphs,
- const float* positions)
- : glyphCount(glyphCount)
- , radius(radius)
- , textSize(paint->getTextSize())
- , typeface(paint->getTypeface())
- , flags(paint->isFakeBoldText() ? Font::kFakeBold : 0)
- , italicStyle(paint->getTextSkewX())
- , scaleX(paint->getTextScaleX())
- , glyphs(srcGlyphs)
- , positions(positions) {}
-
- ~ShadowText() {}
-
- hash_t hash() const;
-
- static int compare(const ShadowText& lhs, const ShadowText& rhs);
-
- bool operator==(const ShadowText& other) const { return compare(*this, other) == 0; }
-
- bool operator!=(const ShadowText& other) const { return compare(*this, other) != 0; }
-
- void copyTextLocally() {
- str.setTo(reinterpret_cast<const char16_t*>(glyphs), glyphCount);
- glyphs = reinterpret_cast<const glyph_t*>(str.string());
- if (positions != nullptr) {
- positionsCopy.clear();
- positionsCopy.appendArray(positions, glyphCount * 2);
- positions = positionsCopy.array();
- }
- }
-
- uint32_t glyphCount;
- float radius;
- float textSize;
- SkTypeface* typeface;
- uint32_t flags;
- float italicStyle;
- float scaleX;
- const glyph_t* glyphs;
- const float* positions;
-
- // Not directly used to compute the cache key
- String16 str;
- Vector<float> positionsCopy;
-
-}; // struct ShadowText
-
-// Caching support
-
-inline int strictly_order_type(const ShadowText& lhs, const ShadowText& rhs) {
- return ShadowText::compare(lhs, rhs) < 0;
-}
-
-inline int compare_type(const ShadowText& lhs, const ShadowText& rhs) {
- return ShadowText::compare(lhs, rhs);
-}
-
-inline hash_t hash_type(const ShadowText& entry) {
- return entry.hash();
-}
-
-/**
- * Alpha texture used to represent a shadow.
- */
-struct ShadowTexture : public Texture {
- explicit ShadowTexture(Caches& caches) : Texture(caches) {}
-
- float left;
- float top;
-}; // struct ShadowTexture
-
-class TextDropShadowCache : public OnEntryRemoved<ShadowText, ShadowTexture*> {
-public:
- TextDropShadowCache();
- explicit TextDropShadowCache(uint32_t maxByteSize);
- ~TextDropShadowCache();
-
- /**
- * Used as a callback when an entry is removed from the cache.
- * Do not invoke directly.
- */
- void operator()(ShadowText& text, ShadowTexture*& texture) override;
-
- ShadowTexture* get(const SkPaint* paint, const glyph_t* text, int numGlyphs, float radius,
- const float* positions);
-
- /**
- * Clears the cache. This causes all textures to be deleted.
- */
- void clear();
-
- void setFontRenderer(FontRenderer& fontRenderer) { mRenderer = &fontRenderer; }
-
- /**
- * Returns the maximum size of the cache in bytes.
- */
- uint32_t getMaxSize();
- /**
- * Returns the current size of the cache in bytes.
- */
- uint32_t getSize();
-
-private:
- LruCache<ShadowText, ShadowTexture*> mCache;
-
- uint32_t mSize;
- const uint32_t mMaxSize;
- FontRenderer* mRenderer = nullptr;
- bool mDebugEnabled;
-}; // class TextDropShadowCache
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_TEXT_DROP_SHADOW_CACHE_H
diff --git a/libs/hwui/font/CacheTexture.cpp b/libs/hwui/font/CacheTexture.cpp
deleted file mode 100644
index 5dd8bb8..0000000
--- a/libs/hwui/font/CacheTexture.cpp
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2012 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 <SkGlyph.h>
-
-#include "../Caches.h"
-#include "../Debug.h"
-#include "../Extensions.h"
-#include "../PixelBuffer.h"
-#include "CacheTexture.h"
-#include "FontUtil.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// CacheBlock
-///////////////////////////////////////////////////////////////////////////////
-
-/**
- * Insert new block into existing linked list of blocks. Blocks are sorted in increasing-width
- * order, except for the final block (the remainder space at the right, since we fill from the
- * left).
- */
-CacheBlock* CacheBlock::insertBlock(CacheBlock* head, CacheBlock* newBlock) {
-#if DEBUG_FONT_RENDERER
- ALOGD("insertBlock: this, x, y, w, h = %p, %d, %d, %d, %d", newBlock, newBlock->mX,
- newBlock->mY, newBlock->mWidth, newBlock->mHeight);
-#endif
-
- CacheBlock* currBlock = head;
- CacheBlock* prevBlock = nullptr;
-
- while (currBlock && currBlock->mY != TEXTURE_BORDER_SIZE) {
- if (newBlock->mWidth < currBlock->mWidth) {
- newBlock->mNext = currBlock;
- newBlock->mPrev = prevBlock;
- currBlock->mPrev = newBlock;
-
- if (prevBlock) {
- prevBlock->mNext = newBlock;
- return head;
- } else {
- return newBlock;
- }
- }
-
- prevBlock = currBlock;
- currBlock = currBlock->mNext;
- }
-
- // new block larger than all others - insert at end (but before the remainder space, if there)
- newBlock->mNext = currBlock;
- newBlock->mPrev = prevBlock;
-
- if (currBlock) {
- currBlock->mPrev = newBlock;
- }
-
- if (prevBlock) {
- prevBlock->mNext = newBlock;
- return head;
- } else {
- return newBlock;
- }
-}
-
-CacheBlock* CacheBlock::removeBlock(CacheBlock* head, CacheBlock* blockToRemove) {
-#if DEBUG_FONT_RENDERER
- ALOGD("removeBlock: this, x, y, w, h = %p, %d, %d, %d, %d", blockToRemove, blockToRemove->mX,
- blockToRemove->mY, blockToRemove->mWidth, blockToRemove->mHeight);
-#endif
-
- CacheBlock* newHead = head;
- CacheBlock* nextBlock = blockToRemove->mNext;
- CacheBlock* prevBlock = blockToRemove->mPrev;
-
- if (prevBlock) {
- // If this doesn't hold, we have a use-after-free below.
- LOG_ALWAYS_FATAL_IF(head == blockToRemove,
- "removeBlock: head should not have a previous block");
- prevBlock->mNext = nextBlock;
- } else {
- newHead = nextBlock;
- }
-
- if (nextBlock) {
- nextBlock->mPrev = prevBlock;
- }
-
- delete blockToRemove;
-
- return newHead;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// CacheTexture
-///////////////////////////////////////////////////////////////////////////////
-
-CacheTexture::CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount)
- : mTexture(Caches::getInstance())
- , mWidth(width)
- , mHeight(height)
- , mFormat(format)
- , mMaxQuadCount(maxQuadCount)
- , mCaches(Caches::getInstance()) {
- mTexture.blend = true;
-
- mCacheBlocks =
- new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
- getWidth() - TEXTURE_BORDER_SIZE, getHeight() - TEXTURE_BORDER_SIZE);
-
- // OpenGL ES 3.0+ lets us specify the row length for unpack operations such
- // as glTexSubImage2D(). This allows us to upload a sub-rectangle of a texture.
- // With OpenGL ES 2.0 we have to upload entire stripes instead.
- mHasUnpackRowLength = mCaches.extensions().hasUnpackRowLength();
-}
-
-CacheTexture::~CacheTexture() {
- releaseMesh();
- releasePixelBuffer();
- reset();
-}
-
-void CacheTexture::reset() {
- // Delete existing cache blocks
- while (mCacheBlocks != nullptr) {
- CacheBlock* tmpBlock = mCacheBlocks;
- mCacheBlocks = mCacheBlocks->mNext;
- delete tmpBlock;
- }
- mNumGlyphs = 0;
- mCurrentQuad = 0;
-}
-
-void CacheTexture::init() {
- // reset, then create a new remainder space to start again
- reset();
- mCacheBlocks =
- new CacheBlock(TEXTURE_BORDER_SIZE, TEXTURE_BORDER_SIZE,
- getWidth() - TEXTURE_BORDER_SIZE, getHeight() - TEXTURE_BORDER_SIZE);
-}
-
-void CacheTexture::releaseMesh() {
- delete[] mMesh;
-}
-
-void CacheTexture::releasePixelBuffer() {
- if (mPixelBuffer) {
- delete mPixelBuffer;
- mPixelBuffer = nullptr;
- }
- mTexture.deleteTexture();
- mDirty = false;
- mCurrentQuad = 0;
-}
-
-void CacheTexture::setLinearFiltering(bool linearFiltering) {
- mTexture.setFilter(linearFiltering ? GL_LINEAR : GL_NEAREST);
-}
-
-void CacheTexture::allocateMesh() {
- if (!mMesh) {
- mMesh = new TextureVertex[mMaxQuadCount * 4];
- }
-}
-
-void CacheTexture::allocatePixelBuffer() {
- if (!mPixelBuffer) {
- mPixelBuffer = PixelBuffer::create(mFormat, getWidth(), getHeight());
- }
-
- GLint internalFormat = mFormat;
- if (mFormat == GL_RGBA) {
- internalFormat = mCaches.rgbaInternalFormat();
- }
-
- mTexture.resize(mWidth, mHeight, internalFormat, mFormat);
- mTexture.setFilter(getLinearFiltering() ? GL_LINEAR : GL_NEAREST);
- mTexture.setWrap(GL_CLAMP_TO_EDGE);
-}
-
-bool CacheTexture::upload() {
- const Rect& dirtyRect = mDirtyRect;
-
- // align the x direction to 32 and y direction to 4 for better performance
- uint32_t x = (((uint32_t)dirtyRect.left) & (~0x1F));
- uint32_t y = (((uint32_t)dirtyRect.top) & (~0x3));
- uint32_t r = ((((uint32_t)dirtyRect.right) + 0x1F) & (~0x1F)) - x;
- uint32_t b = ((((uint32_t)dirtyRect.bottom) + 0x3) & (~0x3)) - y;
- uint32_t width = (r > getWidth() ? getWidth() : r);
- uint32_t height = (b > getHeight() ? getHeight() : b);
-
- // The unpack row length only needs to be specified when a new
- // texture is bound
- if (mHasUnpackRowLength) {
- glPixelStorei(GL_UNPACK_ROW_LENGTH, getWidth());
- } else {
- x = 0;
- width = getWidth();
- }
-
- mPixelBuffer->upload(x, y, width, height);
- setDirty(false);
-
- return mHasUnpackRowLength;
-}
-
-void CacheTexture::setDirty(bool dirty) {
- mDirty = dirty;
- if (!dirty) {
- mDirtyRect.setEmpty();
- }
-}
-
-bool CacheTexture::fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY) {
- switch (glyph.fMaskFormat) {
- case SkMask::kA8_Format:
- case SkMask::kBW_Format:
- if (mFormat != GL_ALPHA) {
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: texture format %x is inappropriate for monochromatic glyphs",
- mFormat);
-#endif
- return false;
- }
- break;
- case SkMask::kARGB32_Format:
- if (mFormat != GL_RGBA) {
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: texture format %x is inappropriate for colour glyphs", mFormat);
-#endif
- return false;
- }
- break;
- default:
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: unknown glyph format %x encountered", glyph.fMaskFormat);
-#endif
- return false;
- }
-
- if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > getHeight()) {
- return false;
- }
-
- uint16_t glyphW = glyph.fWidth + TEXTURE_BORDER_SIZE;
- uint16_t glyphH = glyph.fHeight + TEXTURE_BORDER_SIZE;
-
- // roundedUpW equals glyphW to the next multiple of CACHE_BLOCK_ROUNDING_SIZE.
- // This columns for glyphs that are close but not necessarily exactly the same size. It trades
- // off the loss of a few pixels for some glyphs against the ability to store more glyphs
- // of varying sizes in one block.
- uint16_t roundedUpW = (glyphW + CACHE_BLOCK_ROUNDING_SIZE - 1) & -CACHE_BLOCK_ROUNDING_SIZE;
-
- CacheBlock* cacheBlock = mCacheBlocks;
- while (cacheBlock) {
- // Store glyph in this block iff: it fits the block's remaining space and:
- // it's the remainder space (mY == 0) or there's only enough height for this one glyph
- // or it's within ROUNDING_SIZE of the block width
- if (roundedUpW <= cacheBlock->mWidth && glyphH <= cacheBlock->mHeight &&
- (cacheBlock->mY == TEXTURE_BORDER_SIZE ||
- (cacheBlock->mWidth - roundedUpW < CACHE_BLOCK_ROUNDING_SIZE))) {
- if (cacheBlock->mHeight - glyphH < glyphH) {
- // Only enough space for this glyph - don't bother rounding up the width
- roundedUpW = glyphW;
- }
-
- *retOriginX = cacheBlock->mX;
- *retOriginY = cacheBlock->mY;
-
- // If this is the remainder space, create a new cache block for this column. Otherwise,
- // adjust the info about this column.
- if (cacheBlock->mY == TEXTURE_BORDER_SIZE) {
- uint16_t oldX = cacheBlock->mX;
- // Adjust remainder space dimensions
- cacheBlock->mWidth -= roundedUpW;
- cacheBlock->mX += roundedUpW;
-
- if (getHeight() - glyphH >= glyphH) {
- // There's enough height left over to create a new CacheBlock
- CacheBlock* newBlock =
- new CacheBlock(oldX, glyphH + TEXTURE_BORDER_SIZE, roundedUpW,
- getHeight() - glyphH - TEXTURE_BORDER_SIZE);
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: Created new block: this, x, y, w, h = %p, %d, %d, %d, %d",
- newBlock, newBlock->mX, newBlock->mY, newBlock->mWidth,
- newBlock->mHeight);
-#endif
- mCacheBlocks = CacheBlock::insertBlock(mCacheBlocks, newBlock);
- }
- } else {
- // Insert into current column and adjust column dimensions
- cacheBlock->mY += glyphH;
- cacheBlock->mHeight -= glyphH;
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: Added to existing block: this, x, y, w, h = %p, %d, %d, %d, %d",
- cacheBlock, cacheBlock->mX, cacheBlock->mY, cacheBlock->mWidth,
- cacheBlock->mHeight);
-#endif
- }
-
- if (cacheBlock->mHeight < std::min(glyphH, glyphW)) {
- // If remaining space in this block is too small to be useful, remove it
- mCacheBlocks = CacheBlock::removeBlock(mCacheBlocks, cacheBlock);
- }
-
- mDirty = true;
- const Rect r(*retOriginX - TEXTURE_BORDER_SIZE, *retOriginY - TEXTURE_BORDER_SIZE,
- *retOriginX + glyphW, *retOriginY + glyphH);
- mDirtyRect.unionWith(r);
- mNumGlyphs++;
-
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: current block list:");
- mCacheBlocks->output();
-#endif
-
- return true;
- }
- cacheBlock = cacheBlock->mNext;
- }
-#if DEBUG_FONT_RENDERER
- ALOGD("fitBitmap: returning false for glyph of size %d, %d", glyphW, glyphH);
-#endif
- return false;
-}
-
-uint32_t CacheTexture::calculateFreeMemory() const {
- CacheBlock* cacheBlock = mCacheBlocks;
- uint32_t free = 0;
- // currently only two formats are supported: GL_ALPHA or GL_RGBA;
- uint32_t bpp = mFormat == GL_RGBA ? 4 : 1;
- while (cacheBlock) {
- free += bpp * cacheBlock->mWidth * cacheBlock->mHeight;
- cacheBlock = cacheBlock->mNext;
- }
- return free;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/font/CacheTexture.h b/libs/hwui/font/CacheTexture.h
deleted file mode 100644
index 654378e..0000000
--- a/libs/hwui/font/CacheTexture.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ANDROID_HWUI_CACHE_TEXTURE_H
-#define ANDROID_HWUI_CACHE_TEXTURE_H
-
-#include "PixelBuffer.h"
-#include "Rect.h"
-#include "Texture.h"
-#include "Vertex.h"
-
-#include <GLES3/gl3.h>
-#include <SkGlyph.h>
-#include <utils/Log.h>
-
-namespace android {
-namespace uirenderer {
-
-class Caches;
-
-/**
- * CacheBlock is a node in a linked list of current free space areas in a CacheTexture.
- * Using CacheBlocks enables us to pack the cache from top to bottom as well as left to right.
- * When we add a glyph to the cache, we see if it fits within one of the existing columns that
- * have already been started (this is the case if the glyph fits vertically as well as
- * horizontally, and if its width is sufficiently close to the column width to avoid
- * sub-optimal packing of small glyphs into wide columns). If there is no column in which the
- * glyph fits, we check the final node, which is the remaining space in the cache, creating
- * a new column as appropriate.
- *
- * As columns fill up, we remove their CacheBlock from the list to avoid having to check
- * small blocks in the future.
- */
-struct CacheBlock {
- uint16_t mX;
- uint16_t mY;
- uint16_t mWidth;
- uint16_t mHeight;
- CacheBlock* mNext;
- CacheBlock* mPrev;
-
- CacheBlock(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
- : mX(x), mY(y), mWidth(width), mHeight(height), mNext(nullptr), mPrev(nullptr) {}
-
- static CacheBlock* insertBlock(CacheBlock* head, CacheBlock* newBlock);
- static CacheBlock* removeBlock(CacheBlock* head, CacheBlock* blockToRemove);
-
- void output() {
- CacheBlock* currBlock = this;
- while (currBlock) {
- ALOGD("Block: this, x, y, w, h = %p, %d, %d, %d, %d", currBlock, currBlock->mX,
- currBlock->mY, currBlock->mWidth, currBlock->mHeight);
- currBlock = currBlock->mNext;
- }
- }
-};
-
-class CacheTexture {
-public:
- CacheTexture(uint16_t width, uint16_t height, GLenum format, uint32_t maxQuadCount);
- ~CacheTexture();
-
- void reset();
- void init();
-
- void releaseMesh();
- void releasePixelBuffer();
-
- void allocatePixelBuffer();
- void allocateMesh();
-
- // Returns true if glPixelStorei(GL_UNPACK_ROW_LENGTH) must be reset
- // This method will also call setDirty(false)
- bool upload();
-
- bool fitBitmap(const SkGlyph& glyph, uint32_t* retOriginX, uint32_t* retOriginY);
-
- inline uint16_t getWidth() const { return mWidth; }
-
- inline uint16_t getHeight() const { return mHeight; }
-
- inline GLenum getFormat() const { return mFormat; }
-
- inline uint32_t getOffset(uint16_t x, uint16_t y) const {
- return (y * getWidth() + x) * PixelBuffer::formatSize(mFormat);
- }
-
- inline const Rect* getDirtyRect() const { return &mDirtyRect; }
-
- inline PixelBuffer* getPixelBuffer() const { return mPixelBuffer; }
-
- Texture& getTexture() {
- allocatePixelBuffer();
- return mTexture;
- }
-
- GLuint getTextureId() {
- allocatePixelBuffer();
- return mTexture.id();
- }
-
- inline bool isDirty() const { return mDirty; }
-
- inline bool getLinearFiltering() const { return mLinearFiltering; }
-
- /**
- * This method assumes that the proper texture unit is active.
- */
- void setLinearFiltering(bool linearFiltering);
-
- inline uint16_t getGlyphCount() const { return mNumGlyphs; }
-
- TextureVertex* mesh() const { return mMesh; }
-
- uint32_t meshElementCount() const { return mCurrentQuad * 6; }
-
- uint16_t* indices() const { return (uint16_t*)nullptr; }
-
- void resetMesh() { mCurrentQuad = 0; }
-
- inline void addQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
- float v2, float x3, float y3, float u3, float v3, float x4, float y4,
- float u4, float v4) {
- TextureVertex* mesh = mMesh + mCurrentQuad * 4;
- TextureVertex::set(mesh++, x2, y2, u2, v2);
- TextureVertex::set(mesh++, x3, y3, u3, v3);
- TextureVertex::set(mesh++, x1, y1, u1, v1);
- TextureVertex::set(mesh++, x4, y4, u4, v4);
- mCurrentQuad++;
- }
-
- bool canDraw() const { return mCurrentQuad > 0; }
-
- bool endOfMesh() const { return mCurrentQuad == mMaxQuadCount; }
-
- uint32_t calculateFreeMemory() const;
-
-private:
- void setDirty(bool dirty);
-
- PixelBuffer* mPixelBuffer = nullptr;
- Texture mTexture;
- uint32_t mWidth, mHeight;
- GLenum mFormat;
- bool mLinearFiltering = false;
- bool mDirty = false;
- uint16_t mNumGlyphs = 0;
- TextureVertex* mMesh = nullptr;
- uint32_t mCurrentQuad = 0;
- uint32_t mMaxQuadCount;
- Caches& mCaches;
- CacheBlock* mCacheBlocks;
- bool mHasUnpackRowLength;
- Rect mDirtyRect;
-};
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_CACHE_TEXTURE_H
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
deleted file mode 100644
index 884ccd9..0000000
--- a/libs/hwui/font/Font.cpp
+++ /dev/null
@@ -1,490 +0,0 @@
-/*
- * Copyright (C) 2012 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 <cutils/compiler.h>
-
-#include <utils/JenkinsHash.h>
-#include <utils/Trace.h>
-
-#include <SkGlyph.h>
-#include <SkGlyphCache.h>
-#include <SkSurfaceProps.h>
-#include <SkUtils.h>
-
-#include "../Debug.h"
-#include "../FontRenderer.h"
-#include "../PixelBuffer.h"
-#include "../Properties.h"
-#include "Font.h"
-#include "FontUtil.h"
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Font
-///////////////////////////////////////////////////////////////////////////////
-
-Font::Font(FontRenderer* state, const Font::FontDescription& desc)
- : mState(state), mDescription(desc) {}
-
-Font::FontDescription::FontDescription(const SkPaint* paint, const SkMatrix& rasterMatrix)
- : mLookupTransform(rasterMatrix) {
- mFontId = SkTypeface::UniqueID(paint->getTypeface());
- mFontSize = paint->getTextSize();
- mFlags = 0;
- if (paint->isFakeBoldText()) {
- mFlags |= Font::kFakeBold;
- }
- mItalicStyle = paint->getTextSkewX();
- mScaleX = paint->getTextScaleX();
- mStyle = paint->getStyle();
- mStrokeWidth = paint->getStrokeWidth();
- mAntiAliasing = paint->isAntiAlias();
- mHinting = paint->getHinting();
- if (!mLookupTransform.invert(&mInverseLookupTransform)) {
- ALOGW("Could not query the inverse lookup transform for this font");
- }
-}
-
-Font::~Font() {
- for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
- delete mCachedGlyphs.valueAt(i);
- }
-}
-
-hash_t Font::FontDescription::hash() const {
- uint32_t hash = JenkinsHashMix(0, mFontId);
- hash = JenkinsHashMix(hash, android::hash_type(mFontSize));
- hash = JenkinsHashMix(hash, android::hash_type(mFlags));
- hash = JenkinsHashMix(hash, android::hash_type(mItalicStyle));
- hash = JenkinsHashMix(hash, android::hash_type(mScaleX));
- hash = JenkinsHashMix(hash, android::hash_type(mStyle));
- hash = JenkinsHashMix(hash, android::hash_type(mStrokeWidth));
- hash = JenkinsHashMix(hash, int(mAntiAliasing));
- hash = JenkinsHashMix(hash, android::hash_type(mHinting));
- hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMScaleX]));
- hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMScaleY]));
- return JenkinsHashWhiten(hash);
-}
-
-int Font::FontDescription::compare(const Font::FontDescription& lhs,
- const Font::FontDescription& rhs) {
- int deltaInt = int(lhs.mFontId) - int(rhs.mFontId);
- if (deltaInt != 0) return deltaInt;
-
- if (lhs.mFontSize < rhs.mFontSize) return -1;
- if (lhs.mFontSize > rhs.mFontSize) return +1;
-
- if (lhs.mItalicStyle < rhs.mItalicStyle) return -1;
- if (lhs.mItalicStyle > rhs.mItalicStyle) return +1;
-
- deltaInt = int(lhs.mFlags) - int(rhs.mFlags);
- if (deltaInt != 0) return deltaInt;
-
- if (lhs.mScaleX < rhs.mScaleX) return -1;
- if (lhs.mScaleX > rhs.mScaleX) return +1;
-
- deltaInt = int(lhs.mStyle) - int(rhs.mStyle);
- if (deltaInt != 0) return deltaInt;
-
- if (lhs.mStrokeWidth < rhs.mStrokeWidth) return -1;
- if (lhs.mStrokeWidth > rhs.mStrokeWidth) return +1;
-
- deltaInt = int(lhs.mAntiAliasing) - int(rhs.mAntiAliasing);
- if (deltaInt != 0) return deltaInt;
-
- deltaInt = int(lhs.mHinting) - int(rhs.mHinting);
- if (deltaInt != 0) return deltaInt;
-
- if (lhs.mLookupTransform[SkMatrix::kMScaleX] < rhs.mLookupTransform[SkMatrix::kMScaleX])
- return -1;
- if (lhs.mLookupTransform[SkMatrix::kMScaleX] > rhs.mLookupTransform[SkMatrix::kMScaleX])
- return +1;
-
- if (lhs.mLookupTransform[SkMatrix::kMScaleY] < rhs.mLookupTransform[SkMatrix::kMScaleY])
- return -1;
- if (lhs.mLookupTransform[SkMatrix::kMScaleY] > rhs.mLookupTransform[SkMatrix::kMScaleY])
- return +1;
-
- return 0;
-}
-
-void Font::invalidateTextureCache(CacheTexture* cacheTexture) {
- for (uint32_t i = 0; i < mCachedGlyphs.size(); i++) {
- CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueAt(i);
- if (!cacheTexture || cachedGlyph->mCacheTexture == cacheTexture) {
- cachedGlyph->mIsValid = false;
- }
- }
-}
-
-void Font::measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
- uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
- int width = (int)glyph->mBitmapWidth;
- int height = (int)glyph->mBitmapHeight;
-
- int nPenX = x + glyph->mBitmapLeft;
- int nPenY = y + glyph->mBitmapTop;
-
- if (bounds->bottom > nPenY) {
- bounds->bottom = nPenY;
- }
- if (bounds->left > nPenX) {
- bounds->left = nPenX;
- }
- if (bounds->right < nPenX + width) {
- bounds->right = nPenX + width;
- }
- if (bounds->top < nPenY + height) {
- bounds->top = nPenY + height;
- }
-}
-
-void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapW,
- uint32_t bitmapH, Rect* bounds, const float* pos) {
- float width = (float)glyph->mBitmapWidth;
- float height = (float)glyph->mBitmapHeight;
-
- float nPenX = x + glyph->mBitmapLeft;
- float nPenY = y + glyph->mBitmapTop + height;
-
- float u1 = glyph->mBitmapMinU;
- float u2 = glyph->mBitmapMaxU;
- float v1 = glyph->mBitmapMinV;
- float v2 = glyph->mBitmapMaxV;
-
- mState->appendMeshQuad(nPenX, nPenY, u1, v2, nPenX + width, nPenY, u2, v2, nPenX + width,
- nPenY - height, u2, v1, nPenX, nPenY - height, u1, v1,
- glyph->mCacheTexture);
-}
-
-void Font::drawCachedGlyphTransformed(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
- uint32_t bitmapW, uint32_t bitmapH, Rect* bounds,
- const float* pos) {
- float width = (float)glyph->mBitmapWidth;
- float height = (float)glyph->mBitmapHeight;
-
- SkPoint p[4];
- p[0].iset(glyph->mBitmapLeft, glyph->mBitmapTop + height);
- p[1].iset(glyph->mBitmapLeft + width, glyph->mBitmapTop + height);
- p[2].iset(glyph->mBitmapLeft + width, glyph->mBitmapTop);
- p[3].iset(glyph->mBitmapLeft, glyph->mBitmapTop);
-
- mDescription.mInverseLookupTransform.mapPoints(p, 4);
-
- p[0].offset(x, y);
- p[1].offset(x, y);
- p[2].offset(x, y);
- p[3].offset(x, y);
-
- float u1 = glyph->mBitmapMinU;
- float u2 = glyph->mBitmapMaxU;
- float v1 = glyph->mBitmapMinV;
- float v2 = glyph->mBitmapMaxV;
-
- mState->appendRotatedMeshQuad(p[0].x(), p[0].y(), u1, v2, p[1].x(), p[1].y(), u2, v2, p[2].x(),
- p[2].y(), u2, v1, p[3].x(), p[3].y(), u1, v1,
- glyph->mCacheTexture);
-}
-
-void Font::drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
- uint32_t bitmapWidth, uint32_t bitmapHeight, Rect* bounds,
- const float* pos) {
- int dstX = x + glyph->mBitmapLeft;
- int dstY = y + glyph->mBitmapTop;
-
- CacheTexture* cacheTexture = glyph->mCacheTexture;
- PixelBuffer* pixelBuffer = cacheTexture->getPixelBuffer();
-
- uint32_t formatSize = PixelBuffer::formatSize(pixelBuffer->getFormat());
- uint32_t alpha_channel_offset = PixelBuffer::formatAlphaOffset(pixelBuffer->getFormat());
- uint32_t cacheWidth = cacheTexture->getWidth();
- uint32_t srcStride = formatSize * cacheWidth;
- uint32_t startY = glyph->mStartY * srcStride;
- uint32_t endY = startY + (glyph->mBitmapHeight * srcStride);
-
- const uint8_t* cacheBuffer = pixelBuffer->map();
-
- for (uint32_t cacheY = startY, bitmapY = dstY * bitmapWidth; cacheY < endY;
- cacheY += srcStride, bitmapY += bitmapWidth) {
- for (uint32_t i = 0; i < glyph->mBitmapWidth; ++i) {
- uint8_t* dst = &(bitmap[bitmapY + dstX + i]);
- const uint8_t& src =
- cacheBuffer[cacheY + (glyph->mStartX + i) * formatSize + alpha_channel_offset];
- // Add alpha values to a max of 255, full opacity. This is done to handle
- // fonts/strings where glyphs overlap.
- *dst = std::min(*dst + src, 255);
- }
- }
-}
-
-void Font::drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
- SkPathMeasure& measure, SkPoint* position, SkVector* tangent) {
- const float halfWidth = glyph->mBitmapWidth * 0.5f;
- const float height = glyph->mBitmapHeight;
-
- vOffset += glyph->mBitmapTop + height;
-
- SkPoint destination[4];
- bool ok = measure.getPosTan(x + hOffset + glyph->mBitmapLeft + halfWidth, position, tangent);
- if (!ok) {
- ALOGW("The path for drawTextOnPath is empty or null");
- }
-
- // Move along the tangent and offset by the normal
- destination[0].set(-tangent->fX * halfWidth - tangent->fY * vOffset,
- -tangent->fY * halfWidth + tangent->fX * vOffset);
- destination[1].set(tangent->fX * halfWidth - tangent->fY * vOffset,
- tangent->fY * halfWidth + tangent->fX * vOffset);
- destination[2].set(destination[1].fX + tangent->fY * height,
- destination[1].fY - tangent->fX * height);
- destination[3].set(destination[0].fX + tangent->fY * height,
- destination[0].fY - tangent->fX * height);
-
- const float u1 = glyph->mBitmapMinU;
- const float u2 = glyph->mBitmapMaxU;
- const float v1 = glyph->mBitmapMinV;
- const float v2 = glyph->mBitmapMaxV;
-
- mState->appendRotatedMeshQuad(
- position->x() + destination[0].x(), position->y() + destination[0].y(), u1, v2,
- position->x() + destination[1].x(), position->y() + destination[1].y(), u2, v2,
- position->x() + destination[2].x(), position->y() + destination[2].y(), u2, v1,
- position->x() + destination[3].x(), position->y() + destination[3].y(), u1, v1,
- glyph->mCacheTexture);
-}
-
-CachedGlyphInfo* Font::getCachedGlyph(const SkPaint* paint, glyph_t textUnit, bool precaching) {
- CachedGlyphInfo* cachedGlyph = mCachedGlyphs.valueFor(textUnit);
- if (cachedGlyph) {
- // Is the glyph still in texture cache?
- if (!cachedGlyph->mIsValid) {
- SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
- SkAutoGlyphCacheNoGamma autoCache(*paint, &surfaceProps,
- &mDescription.mLookupTransform);
- const SkGlyph& skiaGlyph = GET_METRICS(autoCache.get(), textUnit);
- updateGlyphCache(paint, skiaGlyph, autoCache.get(), cachedGlyph, precaching);
- }
- } else {
- cachedGlyph = cacheGlyph(paint, textUnit, precaching);
- }
-
- return cachedGlyph;
-}
-
-void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y,
- const float* positions) {
- render(paint, glyphs, numGlyphs, x, y, FRAMEBUFFER, nullptr, 0, 0, nullptr, positions);
-}
-
-void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkPath* path,
- float hOffset, float vOffset) {
- if (numGlyphs == 0 || glyphs == nullptr) {
- return;
- }
-
- int glyphsCount = 0;
- int prevRsbDelta = 0;
-
- float penX = 0.0f;
-
- SkPoint position;
- SkVector tangent;
-
- SkPathMeasure measure(*path, false);
- float pathLength = SkScalarToFloat(measure.getLength());
-
- if (paint->getTextAlign() != SkPaint::kLeft_Align) {
- float textWidth = SkScalarToFloat(paint->measureText(glyphs, numGlyphs * 2));
- float pathOffset = pathLength;
- if (paint->getTextAlign() == SkPaint::kCenter_Align) {
- textWidth *= 0.5f;
- pathOffset *= 0.5f;
- }
- penX += pathOffset - textWidth;
- }
-
- while (glyphsCount < numGlyphs && penX < pathLength) {
- glyph_t glyph = *(glyphs++);
-
- if (IS_END_OF_STRING(glyph)) {
- break;
- }
-
- CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
- penX += AUTO_KERN(prevRsbDelta, cachedGlyph->mLsbDelta);
- prevRsbDelta = cachedGlyph->mRsbDelta;
-
- if (cachedGlyph->mIsValid && cachedGlyph->mCacheTexture) {
- drawCachedGlyph(cachedGlyph, penX, hOffset, vOffset, measure, &position, &tangent);
- }
-
- penX += cachedGlyph->mAdvanceX;
-
- glyphsCount++;
- }
-}
-
-void Font::measure(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, Rect* bounds,
- const float* positions) {
- if (bounds == nullptr) {
- ALOGE("No return rectangle provided to measure text");
- return;
- }
- bounds->set(1e6, -1e6, -1e6, 1e6);
- render(paint, glyphs, numGlyphs, 0, 0, MEASURE, nullptr, 0, 0, bounds, positions);
-}
-
-void Font::precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs) {
- if (numGlyphs == 0 || glyphs == nullptr) {
- return;
- }
-
- int glyphsCount = 0;
- while (glyphsCount < numGlyphs) {
- glyph_t glyph = *(glyphs++);
-
- // Reached the end of the string
- if (IS_END_OF_STRING(glyph)) {
- break;
- }
-
- getCachedGlyph(paint, glyph, true);
- glyphsCount++;
- }
-}
-
-void Font::render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y,
- RenderMode mode, uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH,
- Rect* bounds, const float* positions) {
- if (numGlyphs == 0 || glyphs == nullptr) {
- return;
- }
-
- static RenderGlyph gRenderGlyph[] = {&android::uirenderer::Font::drawCachedGlyph,
- &android::uirenderer::Font::drawCachedGlyphTransformed,
- &android::uirenderer::Font::drawCachedGlyphBitmap,
- &android::uirenderer::Font::drawCachedGlyphBitmap,
- &android::uirenderer::Font::measureCachedGlyph,
- &android::uirenderer::Font::measureCachedGlyph};
- RenderGlyph render = gRenderGlyph[(mode << 1) + !mIdentityTransform];
-
- int glyphsCount = 0;
-
- while (glyphsCount < numGlyphs) {
- glyph_t glyph = *(glyphs++);
-
- // Reached the end of the string
- if (IS_END_OF_STRING(glyph)) {
- break;
- }
-
- CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph);
-
- // If it's still not valid, we couldn't cache it, so we shouldn't
- // draw garbage; also skip empty glyphs (spaces)
- if (cachedGlyph->mIsValid && cachedGlyph->mCacheTexture) {
- int penX = x + (int)roundf(positions[(glyphsCount << 1)]);
- int penY = y + (int)roundf(positions[(glyphsCount << 1) + 1]);
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- mState->historyTracker().glyphRendered(cachedGlyph, penX, penY);
-#endif
- (*this.*render)(cachedGlyph, penX, penY, bitmap, bitmapW, bitmapH, bounds, positions);
- } else {
-#ifdef BUGREPORT_FONT_CACHE_USAGE
- mState->historyTracker().glyphRendered(cachedGlyph, -1, -1);
-#endif
- }
-
- glyphsCount++;
- }
-}
-
-void Font::updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
- SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching) {
- glyph->mAdvanceX = skiaGlyph.fAdvanceX;
- glyph->mAdvanceY = skiaGlyph.fAdvanceY;
- glyph->mBitmapLeft = skiaGlyph.fLeft;
- glyph->mBitmapTop = skiaGlyph.fTop;
- glyph->mLsbDelta = skiaGlyph.fLsbDelta;
- glyph->mRsbDelta = skiaGlyph.fRsbDelta;
-
- uint32_t startX = 0;
- uint32_t startY = 0;
-
- // Get the bitmap for the glyph
- if (!skiaGlyph.fImage) {
- skiaGlyphCache->findImage(skiaGlyph);
- }
- mState->cacheBitmap(skiaGlyph, glyph, &startX, &startY, precaching);
-
- if (!glyph->mIsValid) {
- return;
- }
-
- uint32_t endX = startX + skiaGlyph.fWidth;
- uint32_t endY = startY + skiaGlyph.fHeight;
-
- glyph->mStartX = startX;
- glyph->mStartY = startY;
- glyph->mBitmapWidth = skiaGlyph.fWidth;
- glyph->mBitmapHeight = skiaGlyph.fHeight;
-
- bool empty = skiaGlyph.fWidth == 0 || skiaGlyph.fHeight == 0;
- if (!empty) {
- uint32_t cacheWidth = glyph->mCacheTexture->getWidth();
- uint32_t cacheHeight = glyph->mCacheTexture->getHeight();
-
- glyph->mBitmapMinU = startX / (float)cacheWidth;
- glyph->mBitmapMinV = startY / (float)cacheHeight;
- glyph->mBitmapMaxU = endX / (float)cacheWidth;
- glyph->mBitmapMaxV = endY / (float)cacheHeight;
-
- mState->setTextureDirty();
- }
-}
-
-CachedGlyphInfo* Font::cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching) {
- CachedGlyphInfo* newGlyph = new CachedGlyphInfo();
- mCachedGlyphs.add(glyph, newGlyph);
-
- SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
- SkAutoGlyphCacheNoGamma autoCache(*paint, &surfaceProps, &mDescription.mLookupTransform);
- const SkGlyph& skiaGlyph = GET_METRICS(autoCache.get(), glyph);
- newGlyph->mIsValid = false;
- newGlyph->mGlyphIndex = skiaGlyph.fID;
-
- updateGlyphCache(paint, skiaGlyph, autoCache.get(), newGlyph, precaching);
-
- return newGlyph;
-}
-
-Font* Font::create(FontRenderer* state, const SkPaint* paint, const SkMatrix& matrix) {
- FontDescription description(paint, matrix);
- Font* font = state->mActiveFonts.get(description);
-
- if (!font) {
- font = new Font(state, description);
- state->mActiveFonts.put(description, font);
- }
- font->mIdentityTransform = matrix.isIdentity();
-
- return font;
-}
-
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
deleted file mode 100644
index 85221bc..0000000
--- a/libs/hwui/font/Font.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ANDROID_HWUI_FONT_H
-#define ANDROID_HWUI_FONT_H
-
-#include <vector>
-
-#include <utils/KeyedVector.h>
-
-#include <SkPaint.h>
-#include <SkPathMeasure.h>
-#include <SkScalar.h>
-#include <SkTypeface.h>
-
-#include "../Matrix.h"
-#include "../Rect.h"
-#include "FontUtil.h"
-
-class SkGlyphCache;
-
-namespace android {
-namespace uirenderer {
-
-///////////////////////////////////////////////////////////////////////////////
-// Font
-///////////////////////////////////////////////////////////////////////////////
-
-struct CachedGlyphInfo;
-class CacheTexture;
-class FontRenderer;
-
-/**
- * Represents a font, defined by a Skia font id and a font size. A font is used
- * to generate glyphs and cache them in the FontState.
- */
-class Font {
-public:
- enum Style { kFakeBold = 1 };
-
- struct FontDescription {
- FontDescription(const SkPaint* paint, const SkMatrix& matrix);
-
- static int compare(const FontDescription& lhs, const FontDescription& rhs);
-
- hash_t hash() const;
-
- bool operator==(const FontDescription& other) const { return compare(*this, other) == 0; }
-
- bool operator!=(const FontDescription& other) const { return compare(*this, other) != 0; }
-
- SkFontID mFontId;
- float mFontSize;
- int mFlags;
- float mItalicStyle;
- float mScaleX;
- uint8_t mStyle;
- float mStrokeWidth;
- bool mAntiAliasing;
- uint8_t mHinting;
- SkMatrix mLookupTransform;
- SkMatrix mInverseLookupTransform;
- };
-
- ~Font();
-
- void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y,
- const float* positions);
-
- void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, const SkPath* path,
- float hOffset, float vOffset);
-
- const Font::FontDescription& getDescription() const { return mDescription; }
-
- /**
- * Creates a new font associated with the specified font state.
- */
- static Font* create(FontRenderer* state, const SkPaint* paint, const SkMatrix& matrix);
-
-private:
- friend class FontRenderer;
-
- Font(FontRenderer* state, const Font::FontDescription& desc);
-
- typedef void (Font::*RenderGlyph)(CachedGlyphInfo*, int, int, uint8_t*, uint32_t, uint32_t,
- Rect*, const float*);
-
- enum RenderMode {
- FRAMEBUFFER,
- BITMAP,
- MEASURE,
- };
-
- void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs);
-
- void render(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, int x, int y,
- RenderMode mode, uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds,
- const float* positions);
-
- void measure(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs, Rect* bounds,
- const float* positions);
-
- void invalidateTextureCache(CacheTexture* cacheTexture = nullptr);
-
- CachedGlyphInfo* cacheGlyph(const SkPaint* paint, glyph_t glyph, bool precaching);
- void updateGlyphCache(const SkPaint* paint, const SkGlyph& skiaGlyph,
- SkGlyphCache* skiaGlyphCache, CachedGlyphInfo* glyph, bool precaching);
-
- void measureCachedGlyph(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapW,
- uint32_t bitmapH, Rect* bounds, const float* pos);
- void drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap, uint32_t bitmapW,
- uint32_t bitmapH, Rect* bounds, const float* pos);
- void drawCachedGlyphTransformed(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
- uint32_t bitmapW, uint32_t bitmapH, Rect* bounds,
- const float* pos);
- void drawCachedGlyphBitmap(CachedGlyphInfo* glyph, int x, int y, uint8_t* bitmap,
- uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos);
- void drawCachedGlyph(CachedGlyphInfo* glyph, float x, float hOffset, float vOffset,
- SkPathMeasure& measure, SkPoint* position, SkVector* tangent);
-
- CachedGlyphInfo* getCachedGlyph(const SkPaint* paint, glyph_t textUnit,
- bool precaching = false);
-
- FontRenderer* mState;
- FontDescription mDescription;
-
- // Cache of glyphs
- DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
-
- bool mIdentityTransform;
-};
-
-inline int strictly_order_type(const Font::FontDescription& lhs, const Font::FontDescription& rhs) {
- return Font::FontDescription::compare(lhs, rhs) < 0;
-}
-
-inline int compare_type(const Font::FontDescription& lhs, const Font::FontDescription& rhs) {
- return Font::FontDescription::compare(lhs, rhs);
-}
-
-inline hash_t hash_type(const Font::FontDescription& entry) {
- return entry.hash();
-}
-
-}; // namespace uirenderer
-}; // namespace android
-
-#endif // ANDROID_HWUI_FONT_H
diff --git a/libs/hwui/font/FontCacheHistoryTracker.cpp b/libs/hwui/font/FontCacheHistoryTracker.cpp
deleted file mode 100644
index 5b61c49..0000000
--- a/libs/hwui/font/FontCacheHistoryTracker.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2016 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 "FontCacheHistoryTracker.h"
-
-#include "CacheTexture.h"
-#include "CachedGlyphInfo.h"
-
-namespace android {
-namespace uirenderer {
-
-void FontCacheHistoryTracker::dumpCachedGlyph(String8& log, const CachedGlyph& glyph) {
- log.appendFormat("glyph (texture %p, position: (%d, %d), size: %dx%d, gen: %d)", glyph.texture,
- glyph.startX, glyph.startY, glyph.bitmapW, glyph.bitmapH, glyph.generation);
-}
-
-void FontCacheHistoryTracker::dumpRenderEntry(String8& log, const RenderEntry& entry) {
- if (entry.penX == -1 && entry.penY == -1) {
- log.appendFormat(" glyph skipped in gen: %d\n", entry.glyph.generation);
- } else {
- log.appendFormat(" rendered ");
- dumpCachedGlyph(log, entry.glyph);
- log.appendFormat(" at (%d, %d)\n", entry.penX, entry.penY);
- }
-}
-
-void FontCacheHistoryTracker::dumpUploadEntry(String8& log, const CachedGlyph& glyph) {
- if (glyph.bitmapW == 0 && glyph.bitmapH == 0) {
- log.appendFormat(" cleared cachetexture %p in gen %d\n", glyph.texture,
- glyph.generation);
- } else {
- log.appendFormat(" uploaded ");
- dumpCachedGlyph(log, glyph);
- log.appendFormat("\n");
- }
-}
-
-void FontCacheHistoryTracker::dump(String8& log) const {
- log.appendFormat("FontCacheHistory: \n");
- log.appendFormat(" Upload history: \n");
- for (size_t i = 0; i < mUploadHistory.size(); i++) {
- dumpUploadEntry(log, mUploadHistory[i]);
- }
- log.appendFormat(" Render history: \n");
- for (size_t i = 0; i < mRenderHistory.size(); i++) {
- dumpRenderEntry(log, mRenderHistory[i]);
- }
-}
-
-void FontCacheHistoryTracker::glyphRendered(CachedGlyphInfo* glyphInfo, int penX, int penY) {
- RenderEntry& entry = mRenderHistory.next();
- entry.glyph.generation = generation;
- entry.glyph.texture = glyphInfo->mCacheTexture;
- entry.glyph.startX = glyphInfo->mStartX;
- entry.glyph.startY = glyphInfo->mStartY;
- entry.glyph.bitmapW = glyphInfo->mBitmapWidth;
- entry.glyph.bitmapH = glyphInfo->mBitmapHeight;
- entry.penX = penX;
- entry.penY = penY;
-}
-
-void FontCacheHistoryTracker::glyphUploaded(CacheTexture* texture, uint32_t x, uint32_t y,
- uint16_t glyphW, uint16_t glyphH) {
- CachedGlyph& glyph = mUploadHistory.next();
- glyph.generation = generation;
- glyph.texture = texture;
- glyph.startX = x;
- glyph.startY = y;
- glyph.bitmapW = glyphW;
- glyph.bitmapH = glyphH;
-}
-
-void FontCacheHistoryTracker::glyphsCleared(CacheTexture* texture) {
- CachedGlyph& glyph = mUploadHistory.next();
- glyph.generation = generation;
- glyph.texture = texture;
- glyph.startX = 0;
- glyph.startY = 0;
- glyph.bitmapW = 0;
- glyph.bitmapH = 0;
-}
-
-void FontCacheHistoryTracker::frameCompleted() {
- generation++;
-}
-}; // namespace uirenderer
-}; // namespace android
diff --git a/libs/hwui/font/FontCacheHistoryTracker.h b/libs/hwui/font/FontCacheHistoryTracker.h
deleted file mode 100644
index 4b9cecc..0000000
--- a/libs/hwui/font/FontCacheHistoryTracker.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#pragma once
-#include "../utils/RingBuffer.h"
-
-#include <utils/String8.h>
-
-namespace android {
-namespace uirenderer {
-
-class CacheTexture;
-struct CachedGlyphInfo;
-
-// Tracks glyph uploads and recent rendered/skipped glyphs, so it can give an idea
-// what a missing character is: skipped glyph, wrong coordinates in cache texture etc.
-class FontCacheHistoryTracker {
-public:
- void glyphRendered(CachedGlyphInfo*, int penX, int penY);
- void glyphUploaded(CacheTexture*, uint32_t x, uint32_t y, uint16_t glyphW, uint16_t glyphH);
- void glyphsCleared(CacheTexture*);
- void frameCompleted();
-
- void dump(String8& log) const;
-
-private:
- struct CachedGlyph {
- void* texture;
- uint16_t generation;
- uint16_t startX;
- uint16_t startY;
- uint16_t bitmapW;
- uint16_t bitmapH;
- };
-
- struct RenderEntry {
- CachedGlyph glyph;
- int penX;
- int penY;
- };
-
- static void dumpCachedGlyph(String8& log, const CachedGlyph& glyph);
- static void dumpRenderEntry(String8& log, const RenderEntry& entry);
- static void dumpUploadEntry(String8& log, const CachedGlyph& glyph);
-
- RingBuffer<RenderEntry, 300> mRenderHistory;
- RingBuffer<CachedGlyph, 120> mUploadHistory;
- uint16_t generation = 0;
-};
-
-}; // namespace uirenderer
-}; // namespace android
\ No newline at end of file
diff --git a/libs/hwui/font/FontUtil.h b/libs/hwui/font/FontUtil.h
deleted file mode 100644
index 596e153..0000000
--- a/libs/hwui/font/FontUtil.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 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.
- */
-
-#ifndef ANDROID_HWUI_FONT_UTIL_H
-#define ANDROID_HWUI_FONT_UTIL_H
-
-#include <SkUtils.h>
-
-#include "Properties.h"
-
-///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef TEXTURE_BORDER_SIZE
-#if TEXTURE_BORDER_SIZE != 1
-#error TEXTURE_BORDER_SIZE other than 1 is not currently supported
-#endif
-#else
-#define TEXTURE_BORDER_SIZE 1
-#endif
-
-#define CACHE_BLOCK_ROUNDING_SIZE 4
-
-typedef uint16_t glyph_t;
-#define GET_METRICS(cache, glyph) cache->getGlyphIDMetrics(glyph)
-#define IS_END_OF_STRING(glyph) false
-
-// prev, next are assumed to be signed x.6 fixed-point numbers with range
-// [-1, 1]. Result is an integral float.
-#define AUTO_KERN(prev, next) static_cast<float>(((next) - (prev) + 32) >> 6)
-
-#endif // ANDROID_HWUI_FONT_UTIL_H
diff --git a/libs/hwui/tests/microbench/FontBench.cpp b/libs/hwui/tests/microbench/FontBench.cpp
deleted file mode 100644
index 4e9b540..0000000
--- a/libs/hwui/tests/microbench/FontBench.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 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 "GammaFontRenderer.h"
-#include "tests/common/TestUtils.h"
-
-#include <SkPaint.h>
-
-using namespace android;
-using namespace android::uirenderer;
-
-void BM_FontRenderer_precache_cachehits(benchmark::State& state) {
- TestUtils::runOnRenderThread([&state](renderthread::RenderThread& thread) {
- SkPaint paint;
- paint.setTextSize(20);
- paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- GammaFontRenderer gammaFontRenderer;
- FontRenderer& fontRenderer = gammaFontRenderer.getFontRenderer();
- fontRenderer.setFont(&paint, SkMatrix::I());
-
- std::vector<glyph_t> glyphs;
- std::vector<float> positions;
- float totalAdvance;
- uirenderer::Rect bounds;
- TestUtils::layoutTextUnscaled(paint, "This is a test", &glyphs, &positions, &totalAdvance,
- &bounds);
-
- fontRenderer.precache(&paint, glyphs.data(), glyphs.size(), SkMatrix::I());
-
- while (state.KeepRunning()) {
- fontRenderer.precache(&paint, glyphs.data(), glyphs.size(), SkMatrix::I());
- }
- });
-}
-BENCHMARK(BM_FontRenderer_precache_cachehits);