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

Commit 2359d85e authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Initial HW layer support in new reorderer/renderer"

parents 02a5a6bb 0b7e8245
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ hwui_src_files := \
    Layer.cpp \
    LayerCache.cpp \
    LayerRenderer.cpp \
    LayerUpdateQueue.cpp \
    Matrix.cpp \
    OpenGLRenderer.cpp \
    Patch.cpp \
@@ -204,6 +205,7 @@ LOCAL_SRC_FILES += \
    unit_tests/ClipAreaTests.cpp \
    unit_tests/DamageAccumulatorTests.cpp \
    unit_tests/FatVectorTests.cpp \
    unit_tests/LayerUpdateQueueTests.cpp \
    unit_tests/LinearAllocatorTests.cpp \
    unit_tests/StringUtilsTests.cpp

+31 −15
Original line number Diff line number Diff line
@@ -31,7 +31,9 @@ namespace uirenderer {

OffscreenBuffer::OffscreenBuffer(Caches& caches, uint32_t textureWidth, uint32_t textureHeight,
        uint32_t viewportWidth, uint32_t viewportHeight)
        : texture(caches)
        : viewportWidth(viewportWidth)
        , viewportHeight(viewportHeight)
        , texture(caches)
        , texCoords(0, viewportHeight / float(textureHeight), viewportWidth / float(textureWidth), 0) {
    texture.width = textureWidth;
    texture.height = textureHeight;
@@ -52,12 +54,29 @@ OffscreenBuffer::OffscreenBuffer(Caches& caches, uint32_t textureWidth, uint32_t
// BakedOpRenderer
////////////////////////////////////////////////////////////////////////////////

OffscreenBuffer* BakedOpRenderer::startLayer(uint32_t width, uint32_t height) {
OffscreenBuffer* BakedOpRenderer::createOffscreenBuffer(uint32_t width, uint32_t height) {
    // TODO: get from cache!
    return new OffscreenBuffer(Caches::getInstance(), width, height, width, height);
}

void BakedOpRenderer::destroyOffscreenBuffer(OffscreenBuffer* offscreenBuffer) {
    // destroy and delete, since each clipped saveLayer is only drawn once.
    offscreenBuffer->texture.deleteTexture();

    // TODO: return texture/offscreenbuffer to cache!
    delete offscreenBuffer;
}

OffscreenBuffer* BakedOpRenderer::createLayer(uint32_t width, uint32_t height) {
    LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");

    // TODO: really should be caching these!
    OffscreenBuffer* buffer = new OffscreenBuffer(mCaches, width, height, width, height);
    mRenderTarget.offscreenBuffer = buffer;
    OffscreenBuffer* buffer = createOffscreenBuffer(width, height);
    startLayer(buffer);
    return buffer;
}

void BakedOpRenderer::startLayer(OffscreenBuffer* offscreenBuffer) {
    mRenderTarget.offscreenBuffer = offscreenBuffer;

    // create and bind framebuffer
    mRenderTarget.frameBufferId = mRenderState.genFramebuffer();
@@ -65,7 +84,7 @@ OffscreenBuffer* BakedOpRenderer::startLayer(uint32_t width, uint32_t height) {

    // attach the texture to the FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
            buffer->texture.id, 0);
            offscreenBuffer->texture.id, 0);
    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "startLayer FAILED");
    LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
            "framebuffer incomplete!");
@@ -75,8 +94,7 @@ OffscreenBuffer* BakedOpRenderer::startLayer(uint32_t width, uint32_t height) {
    glClear(GL_COLOR_BUFFER_BIT);

    // Change the viewport & ortho projection
    setViewport(width, height);
    return buffer;
    setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight);
}

void BakedOpRenderer::endLayer() {
@@ -212,23 +230,21 @@ void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op,

    // TODO: extend this to handle HW layers & paint properties which
    // reside in node.properties().layerProperties()
    float layerAlpha = (op.paint->getAlpha() / 255.0f) * state.alpha;
    float layerAlpha = op.alpha * state.alpha;
    const bool tryToSnap = state.computedState.transform.isPureTranslate();
    Glop glop;
    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
            .setRoundRectClipState(state.roundRectClipState)
            .setMeshTexturedUvQuad(nullptr, buffer->texCoords)
            .setFillLayer(buffer->texture, op.paint->getColorFilter(), layerAlpha, PaintUtils::getXfermodeDirect(op.paint), Blend::ModeOrderSwap::NoSwap)
            .setFillLayer(buffer->texture, op.colorFilter, layerAlpha, op.mode, Blend::ModeOrderSwap::NoSwap)
            .setTransform(state.computedState.transform, TransformFlags::None)
            .setModelViewMapUnitToRectOptionalSnap(tryToSnap, op.unmappedBounds)
            .build();
    renderer.renderGlop(state, glop);

    // destroy and delete, since each clipped saveLayer is only drawn once.
    buffer->texture.deleteTexture();

    // TODO: return texture/offscreenbuffer to cache!
    delete buffer;
    if (op.destroy) {
        BakedOpRenderer::destroyOffscreenBuffer(buffer);
    }
}

} // namespace uirenderer
+7 −2
Original line number Diff line number Diff line
@@ -37,7 +37,8 @@ class OffscreenBuffer {
public:
    OffscreenBuffer(Caches& caches, uint32_t textureWidth, uint32_t textureHeight,
            uint32_t viewportWidth, uint32_t viewportHeight);

    uint32_t viewportWidth;
    uint32_t viewportHeight;
    Texture texture;
    Rect texCoords;
    Region region;
@@ -60,12 +61,16 @@ public:
            , mOpaque(opaque) {
    }

    static OffscreenBuffer* createOffscreenBuffer(uint32_t width, uint32_t height);
    static void destroyOffscreenBuffer(OffscreenBuffer*);

    RenderState& renderState() { return mRenderState; }
    Caches& caches() { return mCaches; }

    void startFrame(uint32_t width, uint32_t height);
    void endFrame();
    OffscreenBuffer* startLayer(uint32_t width, uint32_t height);
    OffscreenBuffer* createLayer(uint32_t width, uint32_t height);
    void startLayer(OffscreenBuffer* offscreenBuffer);
    void endLayer();

    Texture* getTexture(const SkBitmap* bitmap);
+5 −1
Original line number Diff line number Diff line
@@ -154,7 +154,11 @@ public:
        return allocator.usedSize();
    }
    bool isEmpty() {
#if HWUI_NEW_OPS
        return ops.empty();
#else
        return !hasDrawOps;
#endif
    }

private:
@@ -179,7 +183,7 @@ private:
    // List of functors
    LsaVector<Functor*> functors;

    bool hasDrawOps;
    bool hasDrawOps; // only used if !HWUI_NEW_OPS

    void cleanupResources();
};
+42 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "LayerUpdateQueue.h"

#include "RenderNode.h"

namespace android {
namespace uirenderer {

void LayerUpdateQueue::clear() {
    mEntries.clear();
}

void LayerUpdateQueue::enqueueLayerWithDamage(RenderNode* renderNode, Rect damage) {
    damage.doIntersect(0, 0, renderNode->getWidth(), renderNode->getHeight());
    if (!damage.isEmpty()) {
        for (Entry& entry : mEntries) {
            if (CC_UNLIKELY(entry.renderNode == renderNode)) {
                entry.damage.unionWith(damage);
                return;
            }
        }
        mEntries.emplace_back(renderNode, damage);
    }
}

} // namespace uirenderer
} // namespace android
Loading