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

Commit 38e0c328 authored by John Reck's avatar John Reck
Browse files

Track texture memory globally

Also mostly consolidates texture creation

Change-Id: Ifea01303afda531dcec99b8fe2a0f64cf2f24420
parent a5abf801
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ hwui_src_files := \
    FrameInfoVisualizer.cpp \
    GammaFontRenderer.cpp \
    GlopBuilder.cpp \
    GpuMemoryTracker.cpp \
    GradientCache.cpp \
    Image.cpp \
    Interpolator.cpp \
@@ -228,6 +229,7 @@ LOCAL_SRC_FILES += \
    tests/unit/DamageAccumulatorTests.cpp \
    tests/unit/DeviceInfoTests.cpp \
    tests/unit/FatVectorTests.cpp \
    tests/unit/GpuMemoryTrackerTests.cpp \
    tests/unit/LayerUpdateQueueTests.cpp \
    tests/unit/LinearAllocatorTests.cpp \
    tests/unit/VectorDrawableTests.cpp \
+20 −37
Original line number Diff line number Diff line
@@ -39,40 +39,22 @@ void AssetAtlas::init(sp<GraphicBuffer> buffer, int64_t* map, int count) {
        if (!mTexture) {
            Caches& caches = Caches::getInstance();
            mTexture = new Texture(caches);
            mTexture->width = buffer->getWidth();
            mTexture->height = buffer->getHeight();
            mTexture->wrap(mImage->getTexture(),
                    buffer->getWidth(), buffer->getHeight(), GL_RGBA);
            createEntries(caches, map, count);
        }
    } else {
        ALOGW("Could not create atlas image");
        delete mImage;
        mImage = nullptr;
        terminate();
    }

    updateTextureId();
}

void AssetAtlas::terminate() {
    if (mImage) {
    delete mImage;
    mImage = nullptr;
        updateTextureId();
    }
}


void AssetAtlas::updateTextureId() {
    mTexture->id = mImage ? mImage->getTexture() : 0;
    if (mTexture->id) {
        // Texture ID changed, force-set to defaults to sync the wrapper & GL
        // state objects
        mTexture->setWrap(GL_CLAMP_TO_EDGE, false, true);
        mTexture->setFilter(GL_NEAREST, false, true);
    }
    for (size_t i = 0; i < mEntries.size(); i++) {
        AssetAtlas::Entry* entry = mEntries.valueAt(i);
        entry->texture->id = mTexture->id;
    }
    delete mTexture;
    mTexture = nullptr;
    mEntries.clear();
}

///////////////////////////////////////////////////////////////////////////////
@@ -80,13 +62,13 @@ void AssetAtlas::updateTextureId() {
///////////////////////////////////////////////////////////////////////////////

AssetAtlas::Entry* AssetAtlas::getEntry(const SkPixelRef* pixelRef) const {
    ssize_t index = mEntries.indexOfKey(pixelRef);
    return index >= 0 ? mEntries.valueAt(index) : nullptr;
    auto result = mEntries.find(pixelRef);
    return result != mEntries.end() ? result->second.get() : nullptr;
}

Texture* AssetAtlas::getEntryTexture(const SkPixelRef* pixelRef) const {
    ssize_t index = mEntries.indexOfKey(pixelRef);
    return index >= 0 ? mEntries.valueAt(index)->texture : nullptr;
    auto result = mEntries.find(pixelRef);
    return result != mEntries.end() ? result->second->texture : nullptr;
}

/**
@@ -94,7 +76,8 @@ Texture* AssetAtlas::getEntryTexture(const SkPixelRef* pixelRef) const {
 * instead of applying the changes to the virtual textures.
 */
struct DelegateTexture: public Texture {
    DelegateTexture(Caches& caches, Texture* delegate): Texture(caches), mDelegate(delegate) { }
    DelegateTexture(Caches& caches, Texture* delegate)
            : Texture(caches), mDelegate(delegate) { }

    virtual void setWrapST(GLenum wrapS, GLenum wrapT, bool bindTexture = false,
            bool force = false, GLenum renderTarget = GL_TEXTURE_2D) override {
@@ -111,8 +94,8 @@ private:
}; // struct DelegateTexture

void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {
    const float width = float(mTexture->width);
    const float height = float(mTexture->height);
    const float width = float(mTexture->width());
    const float height = float(mTexture->height());

    for (int i = 0; i < count; ) {
        SkPixelRef* pixelRef = reinterpret_cast<SkPixelRef*>(map[i++]);
@@ -133,13 +116,13 @@ void AssetAtlas::createEntries(Caches& caches, int64_t* map, int count) {

        Texture* texture = new DelegateTexture(caches, mTexture);
        texture->blend = !SkAlphaTypeIsOpaque(pixelRef->info().alphaType());
        texture->width = pixelRef->info().width();
        texture->height = pixelRef->info().height();
        texture->wrap(mTexture->id(), pixelRef->info().width(),
                pixelRef->info().height(), mTexture->format());

        Entry* entry = new Entry(pixelRef, texture, mapper, *this);
        std::unique_ptr<Entry> entry(new Entry(pixelRef, texture, mapper, *this));
        texture->uvMapper = &entry->uvMapper;

        mEntries.add(entry->pixelRef, entry);
        mEntries.emplace(entry->pixelRef, std::move(entry));
    }
}

+14 −17
Original line number Diff line number Diff line
@@ -17,18 +17,16 @@
#ifndef ANDROID_HWUI_ASSET_ATLAS_H
#define ANDROID_HWUI_ASSET_ATLAS_H

#include <GLES2/gl2.h>

#include <ui/GraphicBuffer.h>

#include <utils/KeyedVector.h>
#include "Texture.h"
#include "UvMapper.h"

#include <cutils/compiler.h>

#include <GLES2/gl2.h>
#include <ui/GraphicBuffer.h>
#include <SkBitmap.h>

#include "Texture.h"
#include "UvMapper.h"
#include <memory>
#include <unordered_map>

namespace android {
namespace uirenderer {
@@ -71,6 +69,10 @@ public:
            return texture->blend ? &atlas.mBlendKey : &atlas.mOpaqueKey;
        }

        ~Entry() {
            delete texture;
        }

    private:
        /**
         * The pixel ref that generated this atlas entry.
@@ -90,10 +92,6 @@ public:
                , atlas(atlas) {
        }

        ~Entry() {
            delete texture;
        }

        friend class AssetAtlas;
    };

@@ -127,7 +125,7 @@ public:
     * Can return 0 if the atlas is not initialized.
     */
    uint32_t getWidth() const {
        return mTexture ? mTexture->width : 0;
        return mTexture ? mTexture->width() : 0;
    }

    /**
@@ -135,7 +133,7 @@ public:
     * Can return 0 if the atlas is not initialized.
     */
    uint32_t getHeight() const {
        return mTexture ? mTexture->height : 0;
        return mTexture ? mTexture->height() : 0;
    }

    /**
@@ -143,7 +141,7 @@ public:
     * Can return 0 if the atlas is not initialized.
     */
    GLuint getTexture() const {
        return mTexture ? mTexture->id : 0;
        return mTexture ? mTexture->id() : 0;
    }

    /**
@@ -160,7 +158,6 @@ public:

private:
    void createEntries(Caches& caches, int64_t* map, int count);
    void updateTextureId();

    Texture* mTexture;
    Image* mImage;
@@ -168,7 +165,7 @@ private:
    const bool mBlendKey;
    const bool mOpaqueKey;

    KeyedVector<const SkPixelRef*, Entry*> mEntries;
    std::unordered_map<const SkPixelRef*, std::unique_ptr<Entry>> mEntries;
}; // class AssetAtlas

}; // namespace uirenderer
+7 −7
Original line number Diff line number Diff line
@@ -217,7 +217,7 @@ static void renderTextShadow(BakedOpRenderer& renderer, FontRenderer& fontRender
            .setMeshTexturedUnitQuad(nullptr)
            .setFillShadowTexturePaint(*texture, textShadow.color, *op.paint, state.alpha)
            .setTransform(state.computedState.transform, TransformFlags::None)
            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width, sy + texture->height))
            .setModelViewMapUnitToRect(Rect(sx, sy, sx + texture->width(), sy + texture->height()))
            .build();
    renderer.renderGlop(state, glop);
}
@@ -337,7 +337,7 @@ static void renderConvexPath(BakedOpRenderer& renderer, const BakedOpState& stat

static void renderPathTexture(BakedOpRenderer& renderer, const BakedOpState& state,
        PathTexture& texture, const RecordedOp& op) {
    Rect dest(texture.width, texture.height);
    Rect dest(texture.width(), texture.height());
    dest.translate(texture.left - texture.offset,
            texture.top - texture.offset);
    Glop glop;
@@ -399,7 +399,7 @@ void BakedOpDispatcher::onBitmapOp(BakedOpRenderer& renderer, const BitmapOp& op
            .setMeshTexturedUnitQuad(texture->uvMapper)
            .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
            .setTransform(state.computedState.transform, TransformFlags::None)
            .setModelViewMapUnitToRectSnap(Rect(texture->width, texture->height))
            .setModelViewMapUnitToRectSnap(Rect(texture->width(), texture->height()))
            .build();
    renderer.renderGlop(state, glop);
}
@@ -483,10 +483,10 @@ void BakedOpDispatcher::onBitmapRectOp(BakedOpRenderer& renderer, const BitmapRe
    if (!texture) return;
    const AutoTexture autoCleanup(texture);

    Rect uv(std::max(0.0f, op.src.left / texture->width),
            std::max(0.0f, op.src.top / texture->height),
            std::min(1.0f, op.src.right / texture->width),
            std::min(1.0f, op.src.bottom / texture->height));
    Rect uv(std::max(0.0f, op.src.left / texture->width()),
            std::max(0.0f, op.src.top / texture->height()),
            std::min(1.0f, op.src.right / texture->width()),
            std::min(1.0f, op.src.bottom / texture->height()));

    const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType)
            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
+3 −3
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const

    // attach the texture to the FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
            offscreenBuffer->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!");
@@ -84,7 +84,7 @@ OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
            area.getWidth(), area.getHeight());
    if (!area.isEmpty()) {
        mCaches.textureState().activateTexture(0);
        mCaches.textureState().bindTexture(buffer->texture.id);
        mCaches.textureState().bindTexture(buffer->texture.id());

        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
                area.left, mRenderTarget.viewportHeight - area.bottom,
@@ -272,7 +272,7 @@ void BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const ClipBase* cli
                    OffscreenBuffer* layer = mRenderTarget.offscreenBuffer;
                    mRenderTarget.stencil = mCaches.renderBufferCache.get(
                            Stencil::getLayerStencilFormat(),
                            layer->texture.width, layer->texture.height);
                            layer->texture.width(), layer->texture.height());
                    // stencil is bound + allocated - associate it with current FBO
                    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                            GL_RENDERBUFFER, mRenderTarget.stencil->getName());
Loading