TestUtils.cpp revision 98c78dad1969e2321cfee2085faa55d95bba7e29
116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck/*
216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Copyright (C) 2015 The Android Open Source Project
316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Licensed under the Apache License, Version 2.0 (the "License");
516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * you may not use this file except in compliance with the License.
616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * You may obtain a copy of the License at
716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *      http://www.apache.org/licenses/LICENSE-2.0
916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck *
1016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * Unless required by applicable law or agreed to in writing, software
1116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * distributed under the License is distributed on an "AS IS" BASIS,
1216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * See the License for the specific language governing permissions and
1416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck * limitations under the License.
1516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck */
1616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
1716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck#include "TestUtils.h"
1816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
1979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger#include "hwui/Paint.h"
20d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik#include "DeferredLayerUpdater.h"
21d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik
227dc370bfe3223dfbcb368e0006c688dfd668ab01sergeyv#include <renderthread/EglManager.h>
2356ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger#include <renderthread/OpenGLPipeline.h>
2498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel#include <pipeline/skia/SkiaOpenGLPipeline.h>
2598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel#include <pipeline/skia/SkiaVulkanPipeline.h>
2698c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel#include <renderthread/VulkanManager.h>
27f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner#include <utils/Unicode.h>
2852771272f4f018f4fc6846224bf047497e784af1Stan Iliev#include <SkClipStack.h>
29f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner
30ee708facf127f2e8bed5970d5c05fa823fcfc1ceLeon Scroggins III#include <SkGlyphCache.h>
31ee708facf127f2e8bed5970d5c05fa823fcfc1ceLeon Scroggins III
3216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Recknamespace android {
3316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Recknamespace uirenderer {
3416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3516c9d6a92e1b86d448c00c52a1630f3e71e6df76John ReckSkColor TestUtils::interpolateColor(float fraction, SkColor start, SkColor end) {
3616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startA = (start >> 24) & 0xff;
3716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startR = (start >> 16) & 0xff;
3816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startG = (start >> 8) & 0xff;
3916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startB = start & 0xff;
4016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
4116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endA = (end >> 24) & 0xff;
4216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endR = (end >> 16) & 0xff;
4316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endG = (end >> 8) & 0xff;
4416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endB = end & 0xff;
4516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
4616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    return (int)((startA + (int)(fraction * (endA - startA))) << 24)
4716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            | (int)((startR + (int)(fraction * (endR - startR))) << 16)
4816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            | (int)((startG + (int)(fraction * (endG - startG))) << 8)
4916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            | (int)((startB + (int)(fraction * (endB - startB))));
5016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck}
5116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
52d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craiksp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
5398c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderthread::RenderThread& renderThread) {
5498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    android::uirenderer::renderthread::IRenderPipeline* pipeline;
5598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    if (Properties::getRenderPipelineType() == RenderPipelineType::OpenGL) {
5698c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        pipeline = new renderthread::OpenGLPipeline(renderThread);
5798c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    } else if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
5898c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        pipeline = new skiapipeline::SkiaOpenGLPipeline(renderThread);
5998c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    } else {
6098c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        pipeline = new skiapipeline::SkiaVulkanPipeline(renderThread);
6198c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    }
6298c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    sp<DeferredLayerUpdater> layerUpdater = pipeline->createTextureLayer();
6398c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    delete pipeline;
6498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    return layerUpdater;
6598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel}
6698c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel
6798c78dad1969e2321cfee2085faa55d95bba7e29Greg Danielsp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
68d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik        renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
69243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik        const SkMatrix& transform) {
7098c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    sp<DeferredLayerUpdater> layerUpdater = createTextureLayerUpdater(renderThread);
7156ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger    layerUpdater->backingLayer()->getTransform().load(transform);
72243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    layerUpdater->setSize(width, height);
73243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    layerUpdater->setTransform(&transform);
74243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik
75243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    // updateLayer so it's ready to draw
7656ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger    layerUpdater->updateLayer(true, GL_TEXTURE_EXTERNAL_OES, Matrix4::identity().data);
77d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    return layerUpdater;
78d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik}
79d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik
80e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craikvoid TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text,
81e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
82e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        float* outTotalAdvance, Rect* outBounds) {
83e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    Rect bounds;
84e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    float totalAdvance = 0;
8542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
86d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
8742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    while (*text != '\0') {
88f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner        size_t nextIndex = 0;
89f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner        int32_t unichar = utf32_from_utf8_at(text, 4, 0, &nextIndex);
90f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner        text += nextIndex;
91f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner
9242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        glyph_t glyph = autoCache.getCache()->unicharToGlyph(unichar);
9342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        autoCache.getCache()->unicharToGlyph(unichar);
94a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
9542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // push glyph and its relative position
96e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outGlyphs->push_back(glyph);
97e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outPositions->push_back(totalAdvance);
98e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outPositions->push_back(0);
99a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
10042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // compute bounds
10142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkGlyph skGlyph = autoCache.getCache()->getUnicharMetrics(unichar);
10242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        Rect glyphBounds(skGlyph.fWidth, skGlyph.fHeight);
10342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        glyphBounds.translate(totalAdvance + skGlyph.fLeft, skGlyph.fTop);
10442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        bounds.unionWith(glyphBounds);
105a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
10642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // advance next character
10742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkScalar skWidth;
10842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        paint.getTextWidths(&glyph, sizeof(glyph), &skWidth, NULL);
10942a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        totalAdvance += skWidth;
11042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    }
111e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    *outBounds = bounds;
112e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    *outTotalAdvance = totalAdvance;
113e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik}
114e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik
11542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik
11679abbf22d4f672208327546661e694d837f564a9Derek Sollenbergervoid TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
11779abbf22d4f672208327546661e694d837f564a9Derek Sollenberger        const SkPaint& paint, float x, float y) {
11879abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    auto utf16 = asciiToUtf16(text);
11979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, 0, paint, nullptr);
120a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik}
121a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
12279abbf22d4f672208327546661e694d837f564a9Derek Sollenbergervoid TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
123d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        const SkPaint& paint, const SkPath& path) {
12479abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    auto utf16 = asciiToUtf16(text);
12579abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    canvas->drawTextOnPath(utf16.get(), strlen(text), 0, path, 0, 0, paint, nullptr);
126d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik}
127d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
128e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reckvoid TestUtils::TestTask::run() {
129e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    // RenderState only valid once RenderThread is running, so queried here
1307dc370bfe3223dfbcb368e0006c688dfd668ab01sergeyv    renderthread::RenderThread& renderThread = renderthread::RenderThread::getInstance();
13198c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
13298c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.vulkanManager().initialize();
13398c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    } else {
13498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.eglManager().initialize();
13598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    }
136e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck
1377dc370bfe3223dfbcb368e0006c688dfd668ab01sergeyv    rtCallback(renderThread);
13856ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger
13998c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
14098c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.vulkanManager().destroy();
14198c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    } else {
14298c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.renderState().flush(Caches::FlushMode::Full);
14398c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.eglManager().destroy();
14498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    }
145e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck}
146e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck
14779abbf22d4f672208327546661e694d837f564a9Derek Sollenbergerstd::unique_ptr<uint16_t[]> TestUtils::asciiToUtf16(const char* str) {
14879abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    const int length = strlen(str);
14979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    std::unique_ptr<uint16_t[]> utf16(new uint16_t[length]);
15079abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    for (int i = 0; i < length; i++) {
15179abbf22d4f672208327546661e694d837f564a9Derek Sollenberger        utf16.get()[i] = str[i];
15279abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    }
15379abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    return utf16;
154dccca44ffda4836b56a21da95a046c9708ffd49csergeyv}
155dccca44ffda4836b56a21da95a046c9708ffd49csergeyv
156021693b967a2c5556dddd183eb0247df4079e1adStan IlievSkColor TestUtils::getColor(const sk_sp<SkSurface>& surface, int x, int y) {
157021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    SkPixmap pixmap;
158021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    if (!surface->peekPixels(&pixmap)) {
159021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        return 0;
160021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
161021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    switch (pixmap.colorType()) {
162021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kGray_8_SkColorType: {
163021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint8_t* addr = pixmap.addr8(x, y);
164021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkColorSetRGB(*addr, *addr, *addr);
165021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
166021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kAlpha_8_SkColorType: {
167021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint8_t* addr = pixmap.addr8(x, y);
168021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkColorSetA(0, addr[0]);
169021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
170021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kRGB_565_SkColorType: {
171021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint16_t* addr = pixmap.addr16(x, y);
172021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkPixel16ToColor(addr[0]);
173021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
174021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kARGB_4444_SkColorType: {
175021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint16_t* addr = pixmap.addr16(x, y);
176021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
177021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkUnPreMultiply::PMColorToColor(c);
178021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
179021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kBGRA_8888_SkColorType: {
180021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint32_t* addr = pixmap.addr32(x, y);
181021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            SkPMColor c = SkSwizzle_BGRA_to_PMColor(addr[0]);
182021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkUnPreMultiply::PMColorToColor(c);
183021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
184021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kRGBA_8888_SkColorType: {
185021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint32_t* addr = pixmap.addr32(x, y);
186021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            SkPMColor c = SkSwizzle_RGBA_to_PMColor(addr[0]);
187021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkUnPreMultiply::PMColorToColor(c);
188021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
189021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        default:
190021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return 0;
191021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
192021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    return 0;
193021693b967a2c5556dddd183eb0247df4079e1adStan Iliev}
194021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
19552771272f4f018f4fc6846224bf047497e784af1Stan IlievSkRect TestUtils::getClipBounds(const SkCanvas* canvas) {
19652771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkClipStack::BoundsType boundType;
19752771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkRect clipBounds;
19852771272f4f018f4fc6846224bf047497e784af1Stan Iliev    canvas->getClipStack()->getBounds(&clipBounds, &boundType);
19952771272f4f018f4fc6846224bf047497e784af1Stan Iliev    return clipBounds;
20052771272f4f018f4fc6846224bf047497e784af1Stan Iliev}
20152771272f4f018f4fc6846224bf047497e784af1Stan Iliev
20252771272f4f018f4fc6846224bf047497e784af1Stan IlievSkRect TestUtils::getLocalClipBounds(const SkCanvas* canvas) {
20352771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkMatrix invertedTotalMatrix;
20452771272f4f018f4fc6846224bf047497e784af1Stan Iliev    if (!canvas->getTotalMatrix().invert(&invertedTotalMatrix)) {
20552771272f4f018f4fc6846224bf047497e784af1Stan Iliev        return SkRect::MakeEmpty();
20652771272f4f018f4fc6846224bf047497e784af1Stan Iliev    }
20752771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkRect outlineInDeviceCoord = TestUtils::getClipBounds(canvas);
20852771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkRect outlineInLocalCoord;
20952771272f4f018f4fc6846224bf047497e784af1Stan Iliev    invertedTotalMatrix.mapRect(&outlineInLocalCoord, outlineInDeviceCoord);
21052771272f4f018f4fc6846224bf047497e784af1Stan Iliev    return outlineInLocalCoord;
21152771272f4f018f4fc6846224bf047497e784af1Stan Iliev}
21252771272f4f018f4fc6846224bf047497e784af1Stan Iliev
21316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck} /* namespace uirenderer */
21416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck} /* namespace android */
215