summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/hwui/DisplayListOp.h4
-rw-r--r--libs/hwui/LayerRenderer.cpp8
-rw-r--r--libs/hwui/LayerRenderer.h8
-rw-r--r--libs/hwui/Matrix.cpp4
-rw-r--r--libs/hwui/Matrix.h4
-rw-r--r--libs/hwui/OpenGLRenderer.cpp74
-rw-r--r--libs/hwui/OpenGLRenderer.h16
-rw-r--r--libs/hwui/font/Font.cpp31
-rw-r--r--libs/hwui/font/Font.h4
9 files changed, 81 insertions, 72 deletions
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 4a724772e413..d231907abb6c 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -1175,8 +1175,8 @@ public:
SkPaint* paint = getPaint(renderer);
FontRenderer& fontRenderer = renderer.getCaches().fontRenderer->getFontRenderer(paint);
const bool pureTranslate = state.mMatrix.isPureTranslate();
- fontRenderer.precache(paint, mText, mCount,
- pureTranslate ? mat4::identity() : state.mMatrix);
+ const mat4 transform = renderer.findBestFontTransform(state.mMatrix);
+ fontRenderer.precache(paint, mText, mCount, transform);
}
virtual status_t applyDraw(OpenGLRenderer& renderer, Rect& dirty, uint32_t level,
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index 14c7c39b39e3..9aa961587ce6 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -92,11 +92,11 @@ void LayerRenderer::finish() {
// who will invoke OpenGLRenderer::resume()
}
-GLint LayerRenderer::getTargetFbo() {
+GLint LayerRenderer::getTargetFbo() const {
return mLayer->getFbo();
}
-bool LayerRenderer::suppressErrorChecks() {
+bool LayerRenderer::suppressErrorChecks() const {
return true;
}
@@ -104,7 +104,7 @@ bool LayerRenderer::suppressErrorChecks() {
// Layer support
///////////////////////////////////////////////////////////////////////////////
-bool LayerRenderer::hasLayer() {
+bool LayerRenderer::hasLayer() const {
return true;
}
@@ -116,7 +116,7 @@ void LayerRenderer::ensureStencilBuffer() {
// Dirty region tracking
///////////////////////////////////////////////////////////////////////////////
-Region* LayerRenderer::getRegion() {
+Region* LayerRenderer::getRegion() const {
if (getSnapshot()->flags & Snapshot::kFlagFboTarget) {
return OpenGLRenderer::getRegion();
}
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index 7a8bdc59d688..5f867317ecf6 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -65,10 +65,10 @@ public:
protected:
virtual void ensureStencilBuffer();
- virtual bool hasLayer();
- virtual Region* getRegion();
- virtual GLint getTargetFbo();
- virtual bool suppressErrorChecks();
+ virtual bool hasLayer() const;
+ virtual Region* getRegion() const;
+ virtual GLint getTargetFbo() const;
+ virtual bool suppressErrorChecks() const;
private:
void generateMesh();
diff --git a/libs/hwui/Matrix.cpp b/libs/hwui/Matrix.cpp
index 204e8f564f11..6a5ea510482b 100644
--- a/libs/hwui/Matrix.cpp
+++ b/libs/hwui/Matrix.cpp
@@ -232,11 +232,11 @@ void Matrix4::copyTo(float* v) const {
memcpy(v, data, sizeof(data));
}
-float Matrix4::getTranslateX() {
+float Matrix4::getTranslateX() const {
return data[kTranslateX];
}
-float Matrix4::getTranslateY() {
+float Matrix4::getTranslateY() const {
return data[kTranslateY];
}
diff --git a/libs/hwui/Matrix.h b/libs/hwui/Matrix.h
index be5bea706e4b..7b7357edf963 100644
--- a/libs/hwui/Matrix.h
+++ b/libs/hwui/Matrix.h
@@ -161,8 +161,8 @@ public:
void mapRect(Rect& r) const;
void mapPoint(float& x, float& y) const;
- float getTranslateX();
- float getTranslateY();
+ float getTranslateX() const;
+ float getTranslateY() const;
void decomposeScale(float& sx, float& sy) const;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 9c1241943236..22ec93b1a5e5 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2627,6 +2627,31 @@ status_t OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count
return DrawGlInfo::kStatusDrew;
}
+mat4 OpenGLRenderer::findBestFontTransform(const mat4& transform) const {
+ mat4 fontTransform;
+ if (CC_LIKELY(transform.isPureTranslate())) {
+ fontTransform = mat4::identity();
+ } else {
+ if (CC_UNLIKELY(transform.isPerspective())) {
+ // When the below condition is true, we are rendering text with a
+ // perspective transform inside a layer (either an inline layer
+ // created by Canvas.saveLayer() or a hardware layer.)
+ if (hasLayer() || getTargetFbo() != 0) {
+ float sx, sy;
+ currentTransform().decomposeScale(sx, sy);
+ fontTransform.loadScale(sx, sy, 1.0f);
+ } else {
+ fontTransform = mat4::identity();
+ }
+ } else {
+ float sx, sy;
+ currentTransform().decomposeScale(sx, sy);
+ fontTransform.loadScale(sx, sy, 1.0f);
+ }
+ }
+ return fontTransform;
+}
+
status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, const float* positions, SkPaint* paint, float length) {
if (text == NULL || count == 0 || mSnapshot->isIgnored() || canSkipText(paint)) {
@@ -2653,12 +2678,13 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
const float oldX = x;
const float oldY = y;
- const bool pureTranslate = currentTransform().isPureTranslate();
- const bool isPerspective = currentTransform().isPerspective();
+
+ const mat4& transform = currentTransform();
+ const bool pureTranslate = transform.isPureTranslate();
if (CC_LIKELY(pureTranslate)) {
- x = (int) floorf(x + currentTransform().getTranslateX() + 0.5f);
- y = (int) floorf(y + currentTransform().getTranslateY() + 0.5f);
+ x = (int) floorf(x + transform.getTranslateX() + 0.5f);
+ y = (int) floorf(y + transform.getTranslateY() + 0.5f);
}
int alpha;
@@ -2675,23 +2701,18 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
const bool hasActiveLayer = hasLayer();
- mat4 fontTransform;
- if (CC_LIKELY(pureTranslate)) {
- fontTransform = mat4::identity();
- } else {
- if (CC_UNLIKELY(isPerspective)) {
- // When the below condition is true, we are rendering text with a
- // perspective transform inside a layer (either an inline layer
- // created by Canvas.saveLayer() or a hardware layer.)
- if (hasActiveLayer || getTargetFbo() != 0) {
- fontTransform = currentTransform();
- } else {
- fontTransform = mat4::identity();
- }
- } else {
- fontTransform = currentTransform();
- }
- }
+ // 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.
+ mat4 fontTransform = findBestFontTransform(transform);
fontRenderer.setFont(paint, fontTransform);
// Pick the appropriate texture filtering
@@ -2708,16 +2729,17 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
setupDrawShader();
setupDrawBlending(true, mode);
setupDrawProgram();
- setupDrawModelView(x, y, x, y, !isPerspective, true);
+ setupDrawModelView(x, y, x, y, pureTranslate, true);
// See comment above; the font renderer must use texture unit 0
// assert(mTextureUnit == 0)
setupDrawTexture(fontRenderer.getTexture(linearFilter));
setupDrawPureColorUniforms();
setupDrawColorFilterUniforms();
- setupDrawShaderUniforms(!isPerspective);
+ setupDrawShaderUniforms(pureTranslate);
setupDrawTextGammaUniforms();
- const Rect* clip = isPerspective ? NULL : mSnapshot->clipRect;
+ // TODO: Implement better clipping for scaled/rotated text
+ const Rect* clip = !pureTranslate ? NULL : mSnapshot->clipRect;
Rect bounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f);
bool status;
@@ -2732,8 +2754,8 @@ status_t OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
}
if (status && hasActiveLayer) {
- if (isPerspective) {
- currentTransform().mapRect(bounds);
+ if (!pureTranslate) {
+ transform.mapRect(bounds);
}
dirtyLayerUnchecked(bounds, getRegion());
}
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index d5423154562d..e961af24161f 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -335,6 +335,12 @@ public:
}
}
+ /**
+ * Return the best transform to use to rasterize text given a full
+ * transform matrix.
+ */
+ mat4 findBestFontTransform(const mat4& transform) const;
+
protected:
/**
* Computes the projection matrix, initialize the first snapshot
@@ -384,28 +390,28 @@ protected:
/**
* Returns the current snapshot.
*/
- sp<Snapshot> getSnapshot() {
+ sp<Snapshot> getSnapshot() const {
return mSnapshot;
}
/**
* Returns the region of the current layer.
*/
- virtual Region* getRegion() {
+ virtual Region* getRegion() const {
return mSnapshot->region;
}
/**
* Indicates whether rendering is currently targeted at a layer.
*/
- virtual bool hasLayer() {
+ virtual bool hasLayer() const {
return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
}
/**
* Returns the name of the FBO this renderer is rendering into.
*/
- virtual GLint getTargetFbo() {
+ virtual GLint getTargetFbo() const {
return 0;
}
@@ -442,7 +448,7 @@ protected:
/**
* Set to true to suppress error checks at the end of a frame.
*/
- virtual bool suppressErrorChecks() {
+ virtual bool suppressErrorChecks() const {
return false;
}
diff --git a/libs/hwui/font/Font.cpp b/libs/hwui/font/Font.cpp
index bf522b7cc734..9307f115392d 100644
--- a/libs/hwui/font/Font.cpp
+++ b/libs/hwui/font/Font.cpp
@@ -53,10 +53,8 @@ Font::FontDescription::FontDescription(const SkPaint* paint, const mat4& matrix)
mStrokeWidth = paint->getStrokeWidth();
mAntiAliasing = paint->isAntiAlias();
mLookupTransform.reset();
- mLookupTransform[SkMatrix::kMScaleX] = matrix.data[mat4::kScaleX];
- mLookupTransform[SkMatrix::kMScaleY] = matrix.data[mat4::kScaleY];
- mLookupTransform[SkMatrix::kMSkewX] = matrix.data[mat4::kSkewX];
- mLookupTransform[SkMatrix::kMSkewY] = matrix.data[mat4::kSkewY];
+ mLookupTransform[SkMatrix::kMScaleX] = matrix[mat4::kScaleX];
+ mLookupTransform[SkMatrix::kMScaleY] = matrix[mat4::kScaleY];
if (!mLookupTransform.invert(&mInverseLookupTransform)) {
ALOGW("Could not query the inverse lookup transform for this font");
}
@@ -81,8 +79,6 @@ hash_t Font::FontDescription::hash() const {
hash = JenkinsHashMix(hash, int(mAntiAliasing));
hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMScaleX]));
hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMScaleY]));
- hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMSkewX]));
- hash = JenkinsHashMix(hash, android::hash_type(mLookupTransform[SkMatrix::kMSkewY]));
return JenkinsHashWhiten(hash);
}
@@ -122,16 +118,6 @@ int Font::FontDescription::compare(const Font::FontDescription& lhs,
if (lhs.mLookupTransform[SkMatrix::kMScaleY] >
rhs.mLookupTransform[SkMatrix::kMScaleY]) return +1;
- if (lhs.mLookupTransform[SkMatrix::kMSkewX] <
- rhs.mLookupTransform[SkMatrix::kMSkewX]) return -1;
- if (lhs.mLookupTransform[SkMatrix::kMSkewX] >
- rhs.mLookupTransform[SkMatrix::kMSkewX]) return +1;
-
- if (lhs.mLookupTransform[SkMatrix::kMSkewY] <
- rhs.mLookupTransform[SkMatrix::kMSkewY]) return -1;
- if (lhs.mLookupTransform[SkMatrix::kMSkewY] >
- rhs.mLookupTransform[SkMatrix::kMSkewY]) return +1;
-
return 0;
}
@@ -185,7 +171,7 @@ void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
nPenX, nPenY - height, u1, v1, glyph->mCacheTexture);
}
-void Font::drawCachedGlyphPerspective(CachedGlyphInfo* glyph, int x, int y,
+void Font::drawCachedGlyphTransformed(CachedGlyphInfo* glyph, int x, int y,
uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH, Rect* bounds, const float* pos) {
SkPoint p[4];
p[0].iset(glyph->mBitmapLeft, glyph->mBitmapTop + glyph->mBitmapHeight);
@@ -388,18 +374,17 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len
static RenderGlyph gRenderGlyph[] = {
&android::uirenderer::Font::drawCachedGlyph,
- &android::uirenderer::Font::drawCachedGlyphPerspective,
+ &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) + mTransform.isPerspective()];
+ RenderGlyph render = gRenderGlyph[(mode << 1) + !mIdentityTransform];
text += start;
int glyphsCount = 0;
- const bool applyTransform = !mTransform.isIdentity() && !mTransform.isPerspective();
const SkPaint::Align align = paint->getTextAlign();
while (glyphsCount < numGlyphs) {
@@ -418,10 +403,6 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len
float penX = x + positions[(glyphsCount << 1)];
float penY = y + positions[(glyphsCount << 1) + 1];
- if (applyTransform) {
- mTransform.mapPoint(penX, penY);
- }
-
(*this.*render)(cachedGlyph, roundf(penX), roundf(penY),
bitmap, bitmapW, bitmapH, bounds, positions);
}
@@ -495,7 +476,7 @@ Font* Font::create(FontRenderer* state, const SkPaint* paint, const mat4& matrix
font = new Font(state, description);
state->mActiveFonts.put(description, font);
}
- font->mTransform.load(matrix);
+ font->mIdentityTransform = matrix.isIdentity();
return font;
}
diff --git a/libs/hwui/font/Font.h b/libs/hwui/font/Font.h
index b2382f4ea319..52cca1c370f3 100644
--- a/libs/hwui/font/Font.h
+++ b/libs/hwui/font/Font.h
@@ -125,7 +125,7 @@ private:
void drawCachedGlyph(CachedGlyphInfo* glyph, int x, int y,
uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH,
Rect* bounds, const float* pos);
- void drawCachedGlyphPerspective(CachedGlyphInfo* glyph, int x, int y,
+ 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,
@@ -142,7 +142,7 @@ private:
// Cache of glyphs
DefaultKeyedVector<glyph_t, CachedGlyphInfo*> mCachedGlyphs;
- mat4 mTransform;
+ bool mIdentityTransform;
};
inline int strictly_order_type(const Font::FontDescription& lhs,