BakedOpDispatcher.cpp revision 9e7fcfda28fde747ba4e026772007cea77374e16
19e7fcfda28fde747ba4e026772007cea77374e16Chris Craik/* 29e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * Copyright (C) 2015 The Android Open Source Project 39e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * 49e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 59e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * you may not use this file except in compliance with the License. 69e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * You may obtain a copy of the License at 79e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * 89e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * http://www.apache.org/licenses/LICENSE-2.0 99e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * 109e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * Unless required by applicable law or agreed to in writing, software 119e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * distributed under the License is distributed on an "AS IS" BASIS, 129e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * See the License for the specific language governing permissions and 149e7fcfda28fde747ba4e026772007cea77374e16Chris Craik * limitations under the License. 159e7fcfda28fde747ba4e026772007cea77374e16Chris Craik */ 169e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 179e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "BakedOpDispatcher.h" 189e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 199e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "BakedOpRenderer.h" 209e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "Caches.h" 219e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "Glop.h" 229e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "GlopBuilder.h" 239e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "renderstate/OffscreenBufferPool.h" 249e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "renderstate/RenderState.h" 259e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "utils/GLUtils.h" 269e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include "VertexBuffer.h" 279e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 289e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include <algorithm> 299e7fcfda28fde747ba4e026772007cea77374e16Chris Craik#include <math.h> 309e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 319e7fcfda28fde747ba4e026772007cea77374e16Chris Craiknamespace android { 329e7fcfda28fde747ba4e026772007cea77374e16Chris Craiknamespace uirenderer { 339e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 349e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onRenderNodeOp(BakedOpRenderer&, const RenderNodeOp&, const BakedOpState&) { 359e7fcfda28fde747ba4e026772007cea77374e16Chris Craik LOG_ALWAYS_FATAL("unsupported operation"); 369e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 379e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 389e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onBeginLayerOp(BakedOpRenderer& renderer, const BeginLayerOp& op, const BakedOpState& state) { 399e7fcfda28fde747ba4e026772007cea77374e16Chris Craik LOG_ALWAYS_FATAL("unsupported operation"); 409e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 419e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 429e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onEndLayerOp(BakedOpRenderer& renderer, const EndLayerOp& op, const BakedOpState& state) { 439e7fcfda28fde747ba4e026772007cea77374e16Chris Craik LOG_ALWAYS_FATAL("unsupported operation"); 449e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 459e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 469e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onBitmapOp(BakedOpRenderer& renderer, const BitmapOp& op, const BakedOpState& state) { 479e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.caches().textureState().activateTexture(0); // TODO: should this be automatic, and/or elsewhere? 489e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Texture* texture = renderer.getTexture(op.bitmap); 499e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (!texture) return; 509e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const AutoTexture autoCleanup(texture); 519e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 529e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType) 539e7fcfda28fde747ba4e026772007cea77374e16Chris Craik ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None; 549e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Glop glop; 559e7fcfda28fde747ba4e026772007cea77374e16Chris Craik GlopBuilder(renderer.renderState(), renderer.caches(), &glop) 569e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setRoundRectClipState(state.roundRectClipState) 579e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setMeshTexturedUnitQuad(texture->uvMapper) 589e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha) 599e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setTransform(state.computedState.transform, TransformFlags::None) 609e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height)) 619e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .build(); 629e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderGlop(state, glop); 639e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 649e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 659e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onLinesOp(BakedOpRenderer& renderer, const LinesOp& op, const BakedOpState& state) { 669e7fcfda28fde747ba4e026772007cea77374e16Chris Craik LOG_ALWAYS_FATAL("todo"); 679e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 689e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 699e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onRectOp(BakedOpRenderer& renderer, const RectOp& op, const BakedOpState& state) { 709e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Glop glop; 719e7fcfda28fde747ba4e026772007cea77374e16Chris Craik GlopBuilder(renderer.renderState(), renderer.caches(), &glop) 729e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setRoundRectClipState(state.roundRectClipState) 739e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setMeshUnitQuad() 749e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setFillPaint(*op.paint, state.alpha) 759e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setTransform(state.computedState.transform, TransformFlags::None) 769e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setModelViewMapUnitToRect(op.unmappedBounds) 779e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .build(); 789e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderGlop(state, glop); 799e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 809e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 819e7fcfda28fde747ba4e026772007cea77374e16Chris Craiknamespace VertexBufferRenderFlags { 829e7fcfda28fde747ba4e026772007cea77374e16Chris Craik enum { 839e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Offset = 0x1, 849e7fcfda28fde747ba4e026772007cea77374e16Chris Craik ShadowInterp = 0x2, 859e7fcfda28fde747ba4e026772007cea77374e16Chris Craik }; 869e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 879e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 889e7fcfda28fde747ba4e026772007cea77374e16Chris Craikstatic void renderVertexBuffer(BakedOpRenderer& renderer, const BakedOpState& state, 899e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const VertexBuffer& vertexBuffer, float translateX, float translateY, 909e7fcfda28fde747ba4e026772007cea77374e16Chris Craik SkPaint& paint, int vertexBufferRenderFlags) { 919e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (CC_LIKELY(vertexBuffer.getVertexCount())) { 929e7fcfda28fde747ba4e026772007cea77374e16Chris Craik bool shadowInterp = vertexBufferRenderFlags & VertexBufferRenderFlags::ShadowInterp; 939e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const int transformFlags = TransformFlags::OffsetByFudgeFactor; 949e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Glop glop; 959e7fcfda28fde747ba4e026772007cea77374e16Chris Craik GlopBuilder(renderer.renderState(), renderer.caches(), &glop) 969e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setRoundRectClipState(state.roundRectClipState) 979e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setMeshVertexBuffer(vertexBuffer, shadowInterp) 989e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setFillPaint(paint, state.alpha) 999e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setTransform(state.computedState.transform, transformFlags) 1009e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setModelViewOffsetRect(translateX, translateY, vertexBuffer.getBounds()) 1019e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .build(); 1029e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderGlop(state, glop); 1039e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1049e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 1059e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1069e7fcfda28fde747ba4e026772007cea77374e16Chris Craikstatic void renderShadow(BakedOpRenderer& renderer, const BakedOpState& state, float casterAlpha, 1079e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const VertexBuffer* ambientShadowVertexBuffer, const VertexBuffer* spotShadowVertexBuffer) { 1089e7fcfda28fde747ba4e026772007cea77374e16Chris Craik SkPaint paint; 1099e7fcfda28fde747ba4e026772007cea77374e16Chris Craik paint.setAntiAlias(true); // want to use AlphaVertex 1109e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1119e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // The caller has made sure casterAlpha > 0. 1129e7fcfda28fde747ba4e026772007cea77374e16Chris Craik uint8_t ambientShadowAlpha = renderer.getLightInfo().ambientShadowAlpha; 1139e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) { 1149e7fcfda28fde747ba4e026772007cea77374e16Chris Craik ambientShadowAlpha = Properties::overrideAmbientShadowStrength; 1159e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1169e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) { 1179e7fcfda28fde747ba4e026772007cea77374e16Chris Craik paint.setAlpha((uint8_t)(casterAlpha * ambientShadowAlpha)); 1189e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderVertexBuffer(renderer, state, *ambientShadowVertexBuffer, 0, 0, 1199e7fcfda28fde747ba4e026772007cea77374e16Chris Craik paint, VertexBufferRenderFlags::ShadowInterp); 1209e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1219e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1229e7fcfda28fde747ba4e026772007cea77374e16Chris Craik uint8_t spotShadowAlpha = renderer.getLightInfo().spotShadowAlpha; 1239e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) { 1249e7fcfda28fde747ba4e026772007cea77374e16Chris Craik spotShadowAlpha = Properties::overrideSpotShadowStrength; 1259e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1269e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (spotShadowVertexBuffer && spotShadowAlpha > 0) { 1279e7fcfda28fde747ba4e026772007cea77374e16Chris Craik paint.setAlpha((uint8_t)(casterAlpha * spotShadowAlpha)); 1289e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderVertexBuffer(renderer, state, *spotShadowVertexBuffer, 0, 0, 1299e7fcfda28fde747ba4e026772007cea77374e16Chris Craik paint, VertexBufferRenderFlags::ShadowInterp); 1309e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1319e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 1329e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1339e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onShadowOp(BakedOpRenderer& renderer, const ShadowOp& op, const BakedOpState& state) { 1349e7fcfda28fde747ba4e026772007cea77374e16Chris Craik TessellationCache::vertexBuffer_pair_t buffers; 1359e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.caches().tessellationCache.getShadowBuffers(&state.computedState.transform, 1369e7fcfda28fde747ba4e026772007cea77374e16Chris Craik op.localClipRect, op.casterAlpha >= 1.0f, op.casterPath, 1379e7fcfda28fde747ba4e026772007cea77374e16Chris Craik &op.shadowMatrixXY, &op.shadowMatrixZ, 1389e7fcfda28fde747ba4e026772007cea77374e16Chris Craik op.lightCenter, renderer.getLightInfo().lightRadius, 1399e7fcfda28fde747ba4e026772007cea77374e16Chris Craik buffers); 1409e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1419e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderShadow(renderer, state, op.casterAlpha, buffers.first, buffers.second); 1429e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 1439e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1449e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onSimpleRectsOp(BakedOpRenderer& renderer, const SimpleRectsOp& op, const BakedOpState& state) { 1459e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Glop glop; 1469e7fcfda28fde747ba4e026772007cea77374e16Chris Craik GlopBuilder(renderer.renderState(), renderer.caches(), &glop) 1479e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setRoundRectClipState(state.roundRectClipState) 1489e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setMeshIndexedQuads(&op.vertices[0], op.vertexCount / 4) 1499e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setFillPaint(*op.paint, state.alpha) 1509e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setTransform(state.computedState.transform, TransformFlags::None) 1519e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setModelViewOffsetRect(0, 0, op.unmappedBounds) 1529e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .build(); 1539e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderGlop(state, glop); 1549e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 1559e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1569e7fcfda28fde747ba4e026772007cea77374e16Chris Craikstatic void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRenderer, 1579e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const TextOp& op, const BakedOpState& state) { 1589e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.caches().textureState().activateTexture(0); 1599e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1609e7fcfda28fde747ba4e026772007cea77374e16Chris Craik PaintUtils::TextShadow textShadow; 1619e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (!PaintUtils::getTextShadow(op.paint, &textShadow)) { 1629e7fcfda28fde747ba4e026772007cea77374e16Chris Craik LOG_ALWAYS_FATAL("failed to query shadow attributes"); 1639e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1649e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1659e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.caches().dropShadowCache.setFontRenderer(fontRenderer); 1669e7fcfda28fde747ba4e026772007cea77374e16Chris Craik ShadowTexture* texture = renderer.caches().dropShadowCache.get( 1679e7fcfda28fde747ba4e026772007cea77374e16Chris Craik op.paint, (const char*) op.glyphs, 1689e7fcfda28fde747ba4e026772007cea77374e16Chris Craik op.glyphCount, textShadow.radius, op.positions); 1699e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // If the drop shadow exceeds the max texture size or couldn't be 1709e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // allocated, skip drawing 1719e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (!texture) return; 1729e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const AutoTexture autoCleanup(texture); 1739e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1749e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const float sx = op.x - texture->left + textShadow.dx; 1759e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const float sy = op.y - texture->top + textShadow.dy; 1769e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1779e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Glop glop; 1789e7fcfda28fde747ba4e026772007cea77374e16Chris Craik GlopBuilder(renderer.renderState(), renderer.caches(), &glop) 1799e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setRoundRectClipState(state.roundRectClipState) 1809e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setMeshTexturedUnitQuad(nullptr) 1819e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setFillShadowTexturePaint(*texture, textShadow.color, *op.paint, state.alpha) 1829e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setTransform(state.computedState.transform, TransformFlags::None) 1839e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height)) 1849e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .build(); 1859e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderGlop(state, glop); 1869e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 1879e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1889e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onTextOp(BakedOpRenderer& renderer, const TextOp& op, const BakedOpState& state) { 1899e7fcfda28fde747ba4e026772007cea77374e16Chris Craik FontRenderer& fontRenderer = renderer.caches().fontRenderer.getFontRenderer(); 1909e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1919e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (CC_UNLIKELY(PaintUtils::hasTextShadow(op.paint))) { 1929e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setFont(op.paint, SkMatrix::I()); 1939e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderTextShadow(renderer, fontRenderer, op, state); 1949e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 1959e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 1969e7fcfda28fde747ba4e026772007cea77374e16Chris Craik float x = op.x; 1979e7fcfda28fde747ba4e026772007cea77374e16Chris Craik float y = op.y; 1989e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const Matrix4& transform = state.computedState.transform; 1999e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const bool pureTranslate = transform.isPureTranslate(); 2009e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (CC_LIKELY(pureTranslate)) { 2019e7fcfda28fde747ba4e026772007cea77374e16Chris Craik x = floorf(x + transform.getTranslateX() + 0.5f); 2029e7fcfda28fde747ba4e026772007cea77374e16Chris Craik y = floorf(y + transform.getTranslateY() + 0.5f); 2039e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setFont(op.paint, SkMatrix::I()); 2049e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setTextureFiltering(false); 2059e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } else if (CC_UNLIKELY(transform.isPerspective())) { 2069e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setFont(op.paint, SkMatrix::I()); 2079e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setTextureFiltering(true); 2089e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } else { 2099e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // We only pass a partial transform to the font renderer. That partial 2109e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // matrix defines how glyphs are rasterized. Typically we want glyphs 2119e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // to be rasterized at their final size on screen, which means the partial 2129e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // matrix needs to take the scale factor into account. 2139e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // When a partial matrix is used to transform glyphs during rasterization, 2149e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // the mesh is generated with the inverse transform (in the case of scale, 2159e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // the mesh is generated at 1.0 / scale for instance.) This allows us to 2169e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // apply the full transform matrix at draw time in the vertex shader. 2179e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // Applying the full matrix in the shader is the easiest way to handle 2189e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // rotation and perspective and allows us to always generated quads in the 2199e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // font renderer which greatly simplifies the code, clipping in particular. 2209e7fcfda28fde747ba4e026772007cea77374e16Chris Craik float sx, sy; 2219e7fcfda28fde747ba4e026772007cea77374e16Chris Craik transform.decomposeScale(sx, sy); 2229e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setFont(op.paint, SkMatrix::MakeScale( 2239e7fcfda28fde747ba4e026772007cea77374e16Chris Craik roundf(std::max(1.0f, sx)), 2249e7fcfda28fde747ba4e026772007cea77374e16Chris Craik roundf(std::max(1.0f, sy)))); 2259e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.setTextureFiltering(true); 2269e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 2279e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2289e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // TODO: Implement better clipping for scaled/rotated text 2299e7fcfda28fde747ba4e026772007cea77374e16Chris Craik const Rect* clip = !pureTranslate ? nullptr : &state.computedState.clipRect; 2309e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Rect layerBounds(FLT_MAX / 2.0f, FLT_MAX / 2.0f, FLT_MIN / 2.0f, FLT_MIN / 2.0f); 2319e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2329e7fcfda28fde747ba4e026772007cea77374e16Chris Craik int alpha = PaintUtils::getAlphaDirect(op.paint) * state.alpha; 2339e7fcfda28fde747ba4e026772007cea77374e16Chris Craik SkXfermode::Mode mode = PaintUtils::getXfermodeDirect(op.paint); 2349e7fcfda28fde747ba4e026772007cea77374e16Chris Craik TextDrawFunctor functor(&renderer, &state, x, y, pureTranslate, alpha, mode, op.paint); 2359e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2369e7fcfda28fde747ba4e026772007cea77374e16Chris Craik bool hasActiveLayer = false; // TODO 2379e7fcfda28fde747ba4e026772007cea77374e16Chris Craik fontRenderer.renderPosText(op.paint, clip, (const char*) op.glyphs, op.glyphCount, x, y, 2389e7fcfda28fde747ba4e026772007cea77374e16Chris Craik op.positions, hasActiveLayer ? &layerBounds : nullptr, &functor, true); // TODO: merging 2399e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 2409e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2419e7fcfda28fde747ba4e026772007cea77374e16Chris Craikvoid BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, const BakedOpState& state) { 2429e7fcfda28fde747ba4e026772007cea77374e16Chris Craik OffscreenBuffer* buffer = *op.layerHandle; 2439e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2449e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // TODO: extend this to handle HW layers & paint properties which 2459e7fcfda28fde747ba4e026772007cea77374e16Chris Craik // reside in node.properties().layerProperties() 2469e7fcfda28fde747ba4e026772007cea77374e16Chris Craik float layerAlpha = op.alpha * state.alpha; 2479e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Glop glop; 2489e7fcfda28fde747ba4e026772007cea77374e16Chris Craik GlopBuilder(renderer.renderState(), renderer.caches(), &glop) 2499e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setRoundRectClipState(state.roundRectClipState) 2509e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setMeshTexturedIndexedVbo(buffer->vbo, buffer->elementCount) 2519e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setFillLayer(buffer->texture, op.colorFilter, layerAlpha, op.mode, Blend::ModeOrderSwap::NoSwap) 2529e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setTransform(state.computedState.transform, TransformFlags::None) 2539e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .setModelViewOffsetRectSnap(op.unmappedBounds.left, op.unmappedBounds.top, 2549e7fcfda28fde747ba4e026772007cea77374e16Chris Craik Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight())) 2559e7fcfda28fde747ba4e026772007cea77374e16Chris Craik .build(); 2569e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderGlop(state, glop); 2579e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2589e7fcfda28fde747ba4e026772007cea77374e16Chris Craik if (op.destroy) { 2599e7fcfda28fde747ba4e026772007cea77374e16Chris Craik renderer.renderState().layerPool().putOrDelete(buffer); 2609e7fcfda28fde747ba4e026772007cea77374e16Chris Craik } 2619e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} 2629e7fcfda28fde747ba4e026772007cea77374e16Chris Craik 2639e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} // namespace uirenderer 2649e7fcfda28fde747ba4e026772007cea77374e16Chris Craik} // namespace android 265