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#include "LayerRenderer.h"
22d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik
2316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Recknamespace android {
2416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Recknamespace uirenderer {
2516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
2616c9d6a92e1b86d448c00c52a1630f3e71e6df76John ReckSkColor TestUtils::interpolateColor(float fraction, SkColor start, SkColor end) {
2716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startA = (start >> 24) & 0xff;
2816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startR = (start >> 16) & 0xff;
2916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startG = (start >> 8) & 0xff;
3016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int startB = start & 0xff;
3116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endA = (end >> 24) & 0xff;
3316c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endR = (end >> 16) & 0xff;
3416c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endG = (end >> 8) & 0xff;
3516c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    int endB = end & 0xff;
3616c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
3716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck    return (int)((startA + (int)(fraction * (endA - startA))) << 24)
3816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            | (int)((startR + (int)(fraction * (endR - startR))) << 16)
3916c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            | (int)((startG + (int)(fraction * (endG - startG))) << 8)
4016c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck            | (int)((startB + (int)(fraction * (endB - startB))));
4116c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck}
4216c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck
43d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craiksp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
44d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik        renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
45243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik        const SkMatrix& transform) {
46243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    Layer* layer = LayerRenderer::createTextureLayer(renderThread.renderState());
47aafb01d8ade0def3f51b74ae3bbc610c4ab33044Chris Craik    layer->getTransform().load(transform);
48243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik
49243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    sp<DeferredLayerUpdater> layerUpdater = new DeferredLayerUpdater(layer);
50243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    layerUpdater->setSize(width, height);
51243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    layerUpdater->setTransform(&transform);
52243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik
53243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    // updateLayer so it's ready to draw
54d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    bool isOpaque = true;
55d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    bool forceFilter = true;
56d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    GLenum renderTarget = GL_TEXTURE_EXTERNAL_OES;
57d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    LayerRenderer::updateTextureLayer(layer, width, height, isOpaque, forceFilter,
58243e85b2e443def1ef47a180e824b36f513c8db8Chris Craik    renderTarget, Matrix4::identity().data);
59d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik
60d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik    return layerUpdater;
61d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik}
62d2dfd8f128b632ed99418ab2b32949c939a9a369Chris Craik
63e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craikvoid TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text,
64e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
65e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        float* outTotalAdvance, Rect* outBounds) {
66e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    Rect bounds;
67e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    float totalAdvance = 0;
6842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    SkSurfaceProps surfaceProps(0, kUnknown_SkPixelGeometry);
69d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik    SkAutoGlyphCacheNoGamma autoCache(paint, &surfaceProps, &SkMatrix::I());
7042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    while (*text != '\0') {
7142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkUnichar unichar = SkUTF8_NextUnichar(&text);
7242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        glyph_t glyph = autoCache.getCache()->unicharToGlyph(unichar);
7342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        autoCache.getCache()->unicharToGlyph(unichar);
74a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
7542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // push glyph and its relative position
76e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outGlyphs->push_back(glyph);
77e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outPositions->push_back(totalAdvance);
78e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik        outPositions->push_back(0);
79a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
8042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // compute bounds
8142a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkGlyph skGlyph = autoCache.getCache()->getUnicharMetrics(unichar);
8242a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        Rect glyphBounds(skGlyph.fWidth, skGlyph.fHeight);
8342a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        glyphBounds.translate(totalAdvance + skGlyph.fLeft, skGlyph.fTop);
8442a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        bounds.unionWith(glyphBounds);
85a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
8642a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        // advance next character
8742a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        SkScalar skWidth;
8842a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        paint.getTextWidths(&glyph, sizeof(glyph), &skWidth, NULL);
8942a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik        totalAdvance += skWidth;
9042a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik    }
91e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    *outBounds = bounds;
92e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik    *outTotalAdvance = totalAdvance;
93e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik}
94e8c3c813b0e3ac98304b17a751ce6e436e252bd9Chris Craik
9542a5407f2c6403ea7aa7a64eaf19948dc4050df5Chris Craik
9679abbf22d4f672208327546661e694d837f564a9Derek Sollenbergervoid TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
9779abbf22d4f672208327546661e694d837f564a9Derek Sollenberger        const SkPaint& paint, float x, float y) {
9879abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    auto utf16 = asciiToUtf16(text);
9979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    canvas->drawText(utf16.get(), 0, strlen(text), strlen(text), x, y, 0, paint, nullptr);
100a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik}
101a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik
10279abbf22d4f672208327546661e694d837f564a9Derek Sollenbergervoid TestUtils::drawUtf8ToCanvas(Canvas* canvas, const char* text,
103d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik        const SkPaint& paint, const SkPath& path) {
10479abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    auto utf16 = asciiToUtf16(text);
10579abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    canvas->drawTextOnPath(utf16.get(), strlen(text), 0, path, 0, 0, paint, nullptr);
106d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik}
107d7448e65e243754f31890baef29dff187dc2e5e5Chris Craik
108e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reckvoid TestUtils::TestTask::run() {
109e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    // RenderState only valid once RenderThread is running, so queried here
110e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    RenderState& renderState = renderthread::RenderThread::getInstance().renderState();
111e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck
112e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    renderState.onGLContextCreated();
113e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    rtCallback(renderthread::RenderThread::getInstance());
1141bc4ee4506b0a113d447d54909e1f8f5c1205563Chris Craik    renderState.flush(Caches::FlushMode::Full);
115e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck    renderState.onGLContextDestroyed();
116e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck}
117e5da4ef971258193cd1e89737a12b95b6ac244bbJohn Reck
11879abbf22d4f672208327546661e694d837f564a9Derek Sollenbergerstd::unique_ptr<uint16_t[]> TestUtils::asciiToUtf16(const char* str) {
11979abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    const int length = strlen(str);
12079abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    std::unique_ptr<uint16_t[]> utf16(new uint16_t[length]);
12179abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    for (int i = 0; i < length; i++) {
12279abbf22d4f672208327546661e694d837f564a9Derek Sollenberger        utf16.get()[i] = str[i];
12379abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    }
12479abbf22d4f672208327546661e694d837f564a9Derek Sollenberger    return utf16;
125dccca44ffda4836b56a21da95a046c9708ffd49csergeyv}
126dccca44ffda4836b56a21da95a046c9708ffd49csergeyv
12716c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck} /* namespace uirenderer */
12816c9d6a92e1b86d448c00c52a1630f3e71e6df76John Reck} /* namespace android */
129