TestUtils.cpp revision 3e9999bd866fac71c72e6b484a9836c87c328a08
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();
633e9999bd866fac71c72e6b484a9836c87c328a08sergeyv    layerUpdater->apply();
6498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    delete pipeline;
6598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    return layerUpdater;
6698c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel}
6798c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel
6898c78dad1969e2321cfee2085faa55d95bba7e29Greg Danielsp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
69d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik        renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
70243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik        const SkMatrix& transform) {
7198c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    sp<DeferredLayerUpdater> layerUpdater = createTextureLayerUpdater(renderThread);
7256ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger    layerUpdater->backingLayer()->getTransform().load(transform);
73243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    layerUpdater->setSize(width, height);
74243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    layerUpdater->setTransform(&transform);
75243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik
76243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    // updateLayer so it's ready to draw
7756ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger    layerUpdater->updateLayer(true, GL_TEXTURE_EXTERNAL_OES, Matrix4::identity().data);
78d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    return layerUpdater;
79d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik}
80d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik
81e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craikvoid TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text,
82e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
83e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        float* outTotalAdvance, Rect* outBounds) {
84e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    Rect bounds;
85e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    float totalAdvance = 0;
8642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
87d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
8842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    while (*text != '\0') {
89f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner        size_t nextIndex = 0;
90f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner        int32_t unichar = utf32_from_utf8_at(text, 4, 0, &nextIndex);
91f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner        text += nextIndex;
92f4cf5d3b019fa60e96219578a4c6ad1a90c7b665Ben Wagner
9342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        glyph_t glyph = autoCache.getCache()->unicharToGlyph(unichar);
9442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        autoCache.getCache()->unicharToGlyph(unichar);
95a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
9642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // push glyph and its relative position
97e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outGlyphs->push_back(glyph);
98e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outPositions->push_back(totalAdvance);
99e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outPositions->push_back(0);
100a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
10142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // compute bounds
10242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkGlyph skGlyph = autoCache.getCache()->getUnicharMetrics(unichar);
10342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        Rect glyphBounds(skGlyph.fWidth, skGlyph.fHeight);
10442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        glyphBounds.translate(totalAdvance + skGlyph.fLeft, skGlyph.fTop);
10542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        bounds.unionWith(glyphBounds);
106a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
10742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // advance next character
10842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkScalar skWidth;
10942a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        paint.getTextWidths(&glyph, sizeof(glyph), &skWidth, NULL);
11042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        totalAdvance += skWidth;
11142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    }
112e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    *outBounds = bounds;
113e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    *outTotalAdvance = totalAdvance;
114e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik}
115e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik
11642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik
11779abbf22d4f672208327546661e694d837f564a9Derek Sollenbergervoid TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
11879abbf22d4f672208327546661e694d837f564a9Derek Sollenberger        const SkPaint& paint, float x, float y) {
11979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    auto utf16 = asciiToUtf16(text);
12079abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, 0, paint, nullptr);
121a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik}
122a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
12379abbf22d4f672208327546661e694d837f564a9Derek Sollenbergervoid TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
124d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        const SkPaint& paint, const SkPath& path) {
12579abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    auto utf16 = asciiToUtf16(text);
12679abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    canvas->drawTextOnPath(utf16.get(), strlen(text), 0, path, 0, 0, paint, nullptr);
127d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik}
128d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
129e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reckvoid TestUtils::TestTask::run() {
130e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    // RenderState only valid once RenderThread is running, so queried here
1317dc370bfe3223dfbcb368e0006c688dfd668ab01sergeyv    renderthread::RenderThread& renderThread = renderthread::RenderThread::getInstance();
13298c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
13398c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.vulkanManager().initialize();
13498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    } else {
13598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.eglManager().initialize();
13698c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    }
137e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck
1387dc370bfe3223dfbcb368e0006c688dfd668ab01sergeyv    rtCallback(renderThread);
13956ad6ec42f814e9e61030ff819cac4e5d31def8bDerek Sollenberger
14098c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
14198c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.vulkanManager().destroy();
14298c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    } else {
14398c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.renderState().flush(Caches::FlushMode::Full);
14498c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel        renderThread.eglManager().destroy();
14598c78dad1969e2321cfee2085faa55d95bba7e29Greg Daniel    }
146e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck}
147e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck
14879abbf22d4f672208327546661e694d837f564a9Derek Sollenbergerstd::unique_ptr<uint16_t[]> TestUtils::asciiToUtf16(const char* str) {
14979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    const int length = strlen(str);
15079abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    std::unique_ptr<uint16_t[]> utf16(new uint16_t[length]);
15179abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    for (int i = 0; i < length; i++) {
15279abbf22d4f672208327546661e694d837f564a9Derek Sollenberger        utf16.get()[i] = str[i];
15379abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    }
15479abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    return utf16;
155dccca44ffda4836b56a21da95a046c9708ffd49csergeyv}
156dccca44ffda4836b56a21da95a046c9708ffd49csergeyv
157021693b967a2c5556dddd183eb0247df4079e1adStan IlievSkColor TestUtils::getColor(const sk_sp<SkSurface>& surface, int x, int y) {
158021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    SkPixmap pixmap;
159021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    if (!surface->peekPixels(&pixmap)) {
160021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        return 0;
161021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
162021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    switch (pixmap.colorType()) {
163021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kGray_8_SkColorType: {
164021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint8_t* addr = pixmap.addr8(x, y);
165021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkColorSetRGB(*addr, *addr, *addr);
166021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
167021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kAlpha_8_SkColorType: {
168021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint8_t* addr = pixmap.addr8(x, y);
169021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkColorSetA(0, addr[0]);
170021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
171021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kRGB_565_SkColorType: {
172021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint16_t* addr = pixmap.addr16(x, y);
173021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkPixel16ToColor(addr[0]);
174021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
175021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kARGB_4444_SkColorType: {
176021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint16_t* addr = pixmap.addr16(x, y);
177021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            SkPMColor c = SkPixel4444ToPixel32(addr[0]);
178021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkUnPreMultiply::PMColorToColor(c);
179021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
180021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kBGRA_8888_SkColorType: {
181021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint32_t* addr = pixmap.addr32(x, y);
182021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            SkPMColor c = SkSwizzle_BGRA_to_PMColor(addr[0]);
183021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkUnPreMultiply::PMColorToColor(c);
184021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
185021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        case kRGBA_8888_SkColorType: {
186021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            const uint32_t* addr = pixmap.addr32(x, y);
187021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            SkPMColor c = SkSwizzle_RGBA_to_PMColor(addr[0]);
188021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return SkUnPreMultiply::PMColorToColor(c);
189021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        }
190021693b967a2c5556dddd183eb0247df4079e1adStan Iliev        default:
191021693b967a2c5556dddd183eb0247df4079e1adStan Iliev            return 0;
192021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    }
193021693b967a2c5556dddd183eb0247df4079e1adStan Iliev    return 0;
194021693b967a2c5556dddd183eb0247df4079e1adStan Iliev}
195021693b967a2c5556dddd183eb0247df4079e1adStan Iliev
19652771272f4f018f4fc6846224bf047497e784af1Stan IlievSkRect TestUtils::getClipBounds(const SkCanvas* canvas) {
1975e4389823191aafff7422561f134dbdb391e0a2dMike Reed    return SkRect::Make(canvas->getDeviceClipBounds());
19852771272f4f018f4fc6846224bf047497e784af1Stan Iliev}
19952771272f4f018f4fc6846224bf047497e784af1Stan Iliev
20052771272f4f018f4fc6846224bf047497e784af1Stan IlievSkRect TestUtils::getLocalClipBounds(const SkCanvas* canvas) {
20152771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkMatrix invertedTotalMatrix;
20252771272f4f018f4fc6846224bf047497e784af1Stan Iliev    if (!canvas->getTotalMatrix().invert(&invertedTotalMatrix)) {
20352771272f4f018f4fc6846224bf047497e784af1Stan Iliev        return SkRect::MakeEmpty();
20452771272f4f018f4fc6846224bf047497e784af1Stan Iliev    }
20552771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkRect outlineInDeviceCoord = TestUtils::getClipBounds(canvas);
20652771272f4f018f4fc6846224bf047497e784af1Stan Iliev    SkRect outlineInLocalCoord;
20752771272f4f018f4fc6846224bf047497e784af1Stan Iliev    invertedTotalMatrix.mapRect(&outlineInLocalCoord, outlineInDeviceCoord);
20852771272f4f018f4fc6846224bf047497e784af1Stan Iliev    return outlineInLocalCoord;
20952771272f4f018f4fc6846224bf047497e784af1Stan Iliev}
21052771272f4f018f4fc6846224bf047497e784af1Stan Iliev
21116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck} /* namespace uirenderer */
21216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck} /* namespace android */
213