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