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

Commit 98fa4f9e authored by sergeyv's avatar sergeyv
Browse files

Use Bitmap in Texture.upload

Test: refactoring cl.
bug:32216791

Change-Id: Ib0b16c878d8371e0471e9a502f55626ec5999c60
parent 81769558
Loading
Loading
Loading
Loading
+18 −22
Original line number Diff line number Diff line
@@ -138,11 +138,6 @@ static void computePathBounds(const SkPath* path, const SkPaint* paint, PathText
    height = uint32_t(pathHeight + texture->offset * 2.0 + 0.5);
}

static void initBitmap(SkBitmap& bitmap, uint32_t width, uint32_t height) {
    bitmap.allocPixels(SkImageInfo::MakeA8(width, height));
    bitmap.eraseColor(0);
}

static void initPaint(SkPaint& paint) {
    // Make sure the paint is opaque, color, alpha, filter, etc.
    // will be applied later when compositing the alpha8 texture
@@ -154,7 +149,7 @@ static void initPaint(SkPaint& paint) {
    paint.setBlendMode(SkBlendMode::kSrc);
}

static SkBitmap* drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
static sk_sp<Bitmap> drawPath(const SkPath* path, const SkPaint* paint, PathTexture* texture,
        uint32_t maxTextureSize) {
    uint32_t width, height;
    computePathBounds(path, paint, texture, width, height);
@@ -164,13 +159,14 @@ static SkBitmap* drawPath(const SkPath* path, const SkPaint* paint, PathTexture*
        return nullptr;
    }

    SkBitmap* bitmap = new SkBitmap();
    initBitmap(*bitmap, width, height);

    sk_sp<Bitmap> bitmap = Bitmap::allocateHeapBitmap(SkImageInfo::MakeA8(width, height));
    SkPaint pathPaint(*paint);
    initPaint(pathPaint);

    SkCanvas canvas(*bitmap);
    SkBitmap skBitmap;
    bitmap->getSkBitmap(&skBitmap);
    skBitmap.eraseColor(0);
    SkCanvas canvas(skBitmap);
    canvas.translate(-texture->left + texture->offset, -texture->top + texture->offset);
    canvas.drawPath(*path, pathPaint);
    return bitmap;
@@ -227,7 +223,7 @@ void PathCache::removeTexture(PathTexture* texture) {

        // If there is a pending task we must wait for it to return
        // before attempting our cleanup
        const sp<Task<SkBitmap*> >& task = texture->task();
        const sp<PathTask>& task = texture->task();
        if (task != nullptr) {
            task->getResult();
            texture->clearTask();
@@ -280,20 +276,20 @@ PathTexture* PathCache::addTexture(const PathDescription& entry, const SkPath *p
    ATRACE_NAME("Generate Path Texture");

    PathTexture* texture = new PathTexture(Caches::getInstance(), path->getGenerationID());
    std::unique_ptr<SkBitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
    if (!bitmap.get()) {
    sk_sp<Bitmap> bitmap(drawPath(path, paint, texture, mMaxTextureSize));
    if (!bitmap) {
        delete texture;
        return nullptr;
    }

    purgeCache(bitmap->width(), bitmap->height());
    generateTexture(entry, bitmap.get(), texture);
    generateTexture(entry, *bitmap, texture);
    return texture;
}

void PathCache::generateTexture(const PathDescription& entry, SkBitmap* bitmap,
void PathCache::generateTexture(const PathDescription& entry, Bitmap& bitmap,
        PathTexture* texture, bool addToCache) {
    generateTexture(*bitmap, texture);
    generateTexture(bitmap, texture);

    // Note here that we upload to a texture even if it's bigger than mMaxSize.
    // Such an entry in mCache will only be temporary, since it will be evicted
@@ -314,7 +310,7 @@ void PathCache::clear() {
    mCache.clear();
}

void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
void PathCache::generateTexture(Bitmap& bitmap, Texture* texture) {
    ATRACE_NAME("Upload Path Texture");
    texture->upload(bitmap);
    texture->setFilter(GL_LINEAR);
@@ -325,10 +321,10 @@ void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
///////////////////////////////////////////////////////////////////////////////

PathCache::PathProcessor::PathProcessor(Caches& caches):
        TaskProcessor<SkBitmap*>(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {
        TaskProcessor<sk_sp<Bitmap> >(&caches.tasks), mMaxTextureSize(caches.maxTextureSize) {
}

void PathCache::PathProcessor::onProcess(const sp<Task<SkBitmap*> >& task) {
void PathCache::PathProcessor::onProcess(const sp<Task<sk_sp<Bitmap> > >& task) {
    PathTask* t = static_cast<PathTask*>(task.get());
    ATRACE_NAME("pathPrecache");

@@ -377,13 +373,13 @@ PathTexture* PathCache::get(const SkPath* path, const SkPaint* paint) {
    } else {
        // A bitmap is attached to the texture, this means we need to
        // upload it as a GL texture
        const sp<Task<SkBitmap*> >& task = texture->task();
        const sp<PathTask>& task = texture->task();
        if (task != nullptr) {
            // But we must first wait for the worker thread to be done
            // producing the bitmap, so let's wait
            SkBitmap* bitmap = task->getResult();
            sk_sp<Bitmap> bitmap = task->getResult();
            if (bitmap) {
                generateTexture(entry, bitmap, texture, false);
                generateTexture(entry, *bitmap, texture, false);
                texture->clearTask();
            } else {
                texture->clearTask();
+23 −27
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "Debug.h"
#include "Texture.h"
#include "hwui/Bitmap.h"
#include "thread/Task.h"
#include "thread/TaskProcessor.h"
#include "utils/Macros.h"
@@ -32,7 +33,6 @@

#include <vector>

class SkBitmap;
class SkCanvas;
class SkPaint;
struct SkRect;
@@ -41,7 +41,6 @@ namespace android {
namespace uirenderer {

class Caches;

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////
@@ -57,6 +56,21 @@ class Caches;
// Classes
///////////////////////////////////////////////////////////////////////////////

struct PathTexture;
class PathTask: public Task<sk_sp<Bitmap>> {
public:
    PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
        path(*path), paint(*paint), texture(texture) {
    }

    // copied, since input path not guaranteed to survive for duration of task
    const SkPath path;

    // copied, since input paint may not be immutable
    const SkPaint paint;
    PathTexture* texture;
};

/**
 * Alpha texture used to represent a path.
 */
@@ -83,11 +97,11 @@ struct PathTexture: public Texture {
     */
    float offset = 0;

    sp<Task<SkBitmap*> > task() const {
    sp<PathTask> task() const {
        return mTask;
    }

    void setTask(const sp<Task<SkBitmap*> >& task) {
    void setTask(const sp<PathTask>& task) {
        mTask = task;
    }

@@ -98,7 +112,7 @@ struct PathTexture: public Texture {
    }

private:
    sp<Task<SkBitmap*> > mTask;
    sp<PathTask> mTask;
}; // struct PathTexture

enum class ShapeType {
@@ -222,13 +236,12 @@ public:
private:
    PathTexture* addTexture(const PathDescription& entry,
            const SkPath *path, const SkPaint* paint);
    PathTexture* addTexture(const PathDescription& entry, SkBitmap* bitmap);

    /**
     * Generates the texture from a bitmap into the specified texture structure.
     */
    void generateTexture(SkBitmap& bitmap, Texture* texture);
    void generateTexture(const PathDescription& entry, SkBitmap* bitmap, PathTexture* texture,
    void generateTexture(Bitmap& bitmap, Texture* texture);
    void generateTexture(const PathDescription& entry, Bitmap& bitmap, PathTexture* texture,
            bool addToCache = true);

    PathTexture* get(const PathDescription& entry) {
@@ -245,30 +258,13 @@ private:

    void init();

    class PathTask: public Task<SkBitmap*> {
    public:
        PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture):
            path(*path), paint(*paint), texture(texture) {
        }

        ~PathTask() {
            delete future()->get();
        }

        // copied, since input path not guaranteed to survive for duration of task
        const SkPath path;

        // copied, since input paint may not be immutable
        const SkPaint paint;
        PathTexture* texture;
    };

    class PathProcessor: public TaskProcessor<SkBitmap*> {
    class PathProcessor: public TaskProcessor<sk_sp<Bitmap> > {
    public:
        explicit PathProcessor(Caches& caches);
        ~PathProcessor() { }

        virtual void onProcess(const sp<Task<SkBitmap*> >& task) override;
        virtual void onProcess(const sp<Task<sk_sp<Bitmap> > >& task) override;

    private:
        uint32_t mMaxTextureSize;
+0 −1
Original line number Diff line number Diff line
@@ -666,7 +666,6 @@ void RecordingCanvas::refBitmapsInShader(const SkShader* shader) {
    SkBitmap bitmap;
    SkShader::TileMode xy[2];
    if (shader->isABitmap(&bitmap, nullptr, xy)) {
        // TODO: create  hwui-owned BitmapShader.
        Bitmap* hwuiBitmap = static_cast<Bitmap*>(bitmap.pixelRef());
        refBitmap(*hwuiBitmap);
        return;
+12 −14
Original line number Diff line number Diff line
@@ -171,12 +171,6 @@ static void uploadToTexture(bool resize, GLint internalFormat, GLenum format, GL
    }
}

static void uploadSkBitmapToTexture(const SkBitmap& bitmap,
        bool resize, GLint internalFormat, GLenum format, GLenum type) {
    uploadToTexture(resize, internalFormat, format, type, bitmap.rowBytesAsPixels(),
            bitmap.bytesPerPixel(), bitmap.width(), bitmap.height(), bitmap.getPixels());
}

static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorType,
        bool needSRGB, GLint* outInternalFormat, GLint* outFormat, GLint* outType) {
    switch (colorType) {
@@ -218,9 +212,7 @@ static void colorTypeToGlFormatAndType(const Caches& caches, SkColorType colorTy
    }
}

void Texture::upload(const SkBitmap& bitmap) {
    SkAutoLockPixels alp(bitmap);

void Texture::upload(Bitmap& bitmap) {
    if (!bitmap.readyToDraw()) {
        ALOGE("Cannot generate texture from bitmap");
        return;
@@ -244,7 +236,7 @@ void Texture::upload(const SkBitmap& bitmap) {
    }

    sk_sp<SkColorSpace> sRGB = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
    bool needSRGB = bitmap.colorSpace() == sRGB.get();
    bool needSRGB = bitmap.info().colorSpace() == sRGB.get();

    GLint internalFormat, format, type;
    colorTypeToGlFormatAndType(mCaches, bitmap.colorType(), needSRGB, &internalFormat, &format, &type);
@@ -264,15 +256,21 @@ void Texture::upload(const SkBitmap& bitmap) {

        SkBitmap rgbaBitmap;
        rgbaBitmap.allocPixels(SkImageInfo::MakeN32(
                mWidth, mHeight, bitmap.alphaType(), hasSRGB ? sRGB : nullptr));
                mWidth, mHeight, bitmap.info().alphaType(), hasSRGB ? sRGB : nullptr));
        rgbaBitmap.eraseColor(0);

        SkCanvas canvas(rgbaBitmap);
        canvas.drawBitmap(bitmap, 0.0f, 0.0f, nullptr);
        SkBitmap skBitmap;
        bitmap.getSkBitmap(&skBitmap);
        canvas.drawBitmap(skBitmap, 0.0f, 0.0f, nullptr);

        uploadToTexture(needsAlloc, internalFormat, format, type, rgbaBitmap.rowBytesAsPixels(),
                rgbaBitmap.bytesPerPixel(), rgbaBitmap.width(),
                rgbaBitmap.height(), rgbaBitmap.getPixels());

        uploadSkBitmapToTexture(rgbaBitmap, needsAlloc, internalFormat, format, type);
    } else {
        uploadSkBitmapToTexture(bitmap, needsAlloc, internalFormat, format, type);
        uploadToTexture(needsAlloc, internalFormat, format, type, bitmap.rowBytesAsPixels(),
                bitmap.info().bytesPerPixel(), bitmap.width(), bitmap.height(), bitmap.pixels());
    }

    if (canMipMap) {
+4 −4
Original line number Diff line number Diff line
@@ -18,9 +18,9 @@
#define ANDROID_HWUI_TEXTURE_H

#include "GpuMemoryTracker.h"
#include "hwui/Bitmap.h"

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

namespace android {
namespace uirenderer {
@@ -74,13 +74,13 @@ public:
    }

    /**
     * Updates this Texture with the contents of the provided SkBitmap,
     * Updates this Texture with the contents of the provided Bitmap,
     * also setting the appropriate width, height, and format. It is not necessary
     * to call resize() prior to this.
     *
     * Note this does not set the generation from the SkBitmap.
     * Note this does not set the generation from the Bitmap.
     */
    void upload(const SkBitmap& source);
    void upload(Bitmap& source);

    /**
     * Basically glTexImage2D/glTexSubImage2D.
Loading