Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e22425bd authored by Leon Scroggins's avatar Leon Scroggins Committed by Android (Google) Code Review
Browse files

Merge "RenderEngine: draw A8 buffers with a color filter"

parents 390c0e9b 2c1d9ef1
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -1104,6 +1104,15 @@ void SkiaGLRenderEngine::drawLayersInternal(
                paint.setDither(true);
            }
            paint.setAlphaf(layer.alpha);

            if (imageTextureRef->colorType() == kAlpha_8_SkColorType) {
                LOG_ALWAYS_FATAL_IF(layer.disableBlending, "Cannot disableBlending with A8");
                float matrix[] = { 0, 0, 0, 0, 0,
                                   0, 0, 0, 0, 0,
                                   0, 0, 0, 0, 0,
                                   0, 0, 0, -1, 1 };
                paint.setColorFilter(SkColorFilters::Matrix(matrix));
            }
        } else {
            ATRACE_NAME("DrawColor");
            const auto color = layer.source.solidColor;
@@ -1125,7 +1134,11 @@ void SkiaGLRenderEngine::drawLayersInternal(
            paint.setBlendMode(SkBlendMode::kSrc);
        }

        // A color filter will have been set for an A8 buffer. Do not replace
        // it with the displayColorTransform, which shouldn't affect A8.
        if (!paint.getColorFilter()) {
            paint.setColorFilter(displayColorTransform);
        }

        if (!roundRectClip.isEmpty()) {
            canvas->clipRRect(roundRectClip, true);
+85 −4
Original line number Diff line number Diff line
@@ -218,14 +218,35 @@ public:
        uint8_t* pixels;
        buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                                  reinterpret_cast<void**>(&pixels));
        pixels[0] = color.r;
        pixels[1] = color.g;
        pixels[2] = color.b;
        pixels[3] = color.a;
        for (uint32_t j = 0; j < height; j++) {
            uint8_t* dst = pixels + (buffer->getBuffer()->getStride() * j * 4);
            for (uint32_t i = 0; i < width; i++) {
                dst[0] = color.r;
                dst[1] = color.g;
                dst[2] = color.b;
                dst[3] = color.a;
                dst += 4;
            }
        }
        buffer->getBuffer()->unlock();
        return buffer;
    }

    std::shared_ptr<renderengine::ExternalTexture> allocateR8Buffer(int width, int height) {
        auto buffer = new GraphicBuffer(width, height, android::PIXEL_FORMAT_R_8, 1,
                                        GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
                                                GRALLOC_USAGE_HW_TEXTURE,
                                        "r8");
        if (buffer->initCheck() != 0) {
            // Devices are not required to support R8.
            return nullptr;
        }
        return std::make_shared<
                renderengine::impl::ExternalTexture>(std::move(buffer), *mRE,
                                                     renderengine::impl::ExternalTexture::Usage::
                                                             READABLE);
    }

    RenderEngineTest() {
        const ::testing::TestInfo* const test_info =
                ::testing::UnitTest::GetInstance()->current_test_info();
@@ -2541,6 +2562,66 @@ TEST_P(RenderEngineTest, test_tonemapPQMatches) {

    expectBufferColor(Rect(kGreyLevels, 1), generator, 2);
}

TEST_P(RenderEngineTest, r8_behaves_as_mask) {
    if (GetParam()->type() == renderengine::RenderEngine::RenderEngineType::GLES) {
        return;
    }

    initializeRenderEngine();

    const auto r8Buffer = allocateR8Buffer(2, 1);
    if (!r8Buffer) {
        return;
    }
    {
        uint8_t* pixels;
        r8Buffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                                    reinterpret_cast<void**>(&pixels));
        // This will be drawn on top of a green buffer. We'll verify that 255
        // results in keeping the original green and 0 results in black.
        pixels[0] = 0;
        pixels[1] = 255;
        r8Buffer->getBuffer()->unlock();
    }

    const auto rect = Rect(0, 0, 2, 1);
    const renderengine::DisplaySettings display{
            .physicalDisplay = rect,
            .clip = rect,
            .outputDataspace = ui::Dataspace::SRGB,
    };

    const auto greenBuffer = allocateAndFillSourceBuffer(2, 1, ubyte4(0, 255, 0, 255));
    const renderengine::LayerSettings greenLayer{
            .geometry.boundaries = rect.toFloatRect(),
            .source =
                    renderengine::PixelSource{
                            .buffer =
                                    renderengine::Buffer{
                                            .buffer = greenBuffer,
                                    },
                    },
            .alpha = 1.0f,
    };
    const renderengine::LayerSettings r8Layer{
            .geometry.boundaries = rect.toFloatRect(),
            .source =
                    renderengine::PixelSource{
                            .buffer =
                                    renderengine::Buffer{
                                            .buffer = r8Buffer,
                                    },
                    },
            .alpha = 1.0f,
    };

    std::vector<renderengine::LayerSettings> layers{greenLayer, r8Layer};
    invokeDraw(display, layers);

    expectBufferColor(Rect(0, 0, 1, 1), 0,   0, 0, 255);
    expectBufferColor(Rect(1, 0, 2, 1), 0, 255, 0, 255);
}
} // namespace renderengine
} // namespace android