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

Commit cd56408b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Update VectorDrawables cache at frame start"

parents d9f5d75d 23c38a9e
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -491,6 +491,36 @@ Bitmap& Tree::getBitmapUpdateIfDirty() {
    return *mCache.bitmap;
}

void Tree::updateCache(sk_sp<SkSurface> surface) {
    if (surface.get()) {
        mCache.surface = surface;
    }
    if (surface.get() || mCache.dirty) {
        SkSurface* vdSurface = mCache.surface.get();
        SkCanvas* canvas = vdSurface->getCanvas();
        float scaleX = vdSurface->width() / mProperties.getViewportWidth();
        float scaleY = vdSurface->height() / mProperties.getViewportHeight();
        SkAutoCanvasRestore acr(canvas, true);
        canvas->clear(SK_ColorTRANSPARENT);
        canvas->scale(scaleX, scaleY);
        mRootNode->draw(canvas, false);
        mCache.dirty = false;
        canvas->flush();
    }
}

void Tree::draw(SkCanvas* canvas) {
   /*
    * TODO address the following...
    *
    * 1) figure out how to set path's as volatile during animation
    * 2) if mRoot->getPaint() != null either promote to layer (during
    *    animation) or cache in SkSurface (for static content)
    */
    canvas->drawImageRect(mCache.surface->makeImageSnapshot().get(),
        mutateProperties()->getBounds(), getPaint());
}

void Tree::updateBitmapCache(Bitmap& bitmap, bool useStagingData) {
    SkBitmap outCache;
    bitmap.getSkBitmap(&outCache);
+24 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <SkPathMeasure.h>
#include <SkRect.h>
#include <SkShader.h>
#include <SkSurface.h>

#include <cutils/compiler.h>
#include <stddef.h>
@@ -677,15 +678,37 @@ public:
    // This should only be called from animations on RT
    TreeProperties* mutateProperties() { return &mProperties; }

    // called from RT only
    const TreeProperties& properties() const { return mProperties; }

    // This should always be called from RT.
    void markDirty() { mCache.dirty = true; }
    bool isDirty() const { return mCache.dirty; }
    bool getPropertyChangeWillBeConsumed() const { return mWillBeConsumed; }
    void setPropertyChangeWillBeConsumed(bool willBeConsumed) { mWillBeConsumed = willBeConsumed; }

    // Returns true if VD cache surface is big enough. This should always be called from RT and it
    // works with Skia pipelines only.
    bool canReuseSurface() {
        SkSurface* surface = mCache.surface.get();
        return surface && surface->width() >= mProperties.getScaledWidth()
              && surface->height() >= mProperties.getScaledHeight();
    }

    // Draws VD cache into a canvas. This should always be called from RT and it works with Skia
    // pipelines only.
    void draw(SkCanvas* canvas);

    // Draws VD into a GPU backed surface. If canReuseSurface returns false, then "surface" must
    // contain a new surface. This should always be called from RT and it works with Skia pipelines
    // only.
    void updateCache(sk_sp<SkSurface> surface);

private:
    struct Cache {
        sk_sp<Bitmap> bitmap;
        sk_sp<Bitmap> bitmap; //used by HWUI pipeline and software
        //TODO: use surface instead of bitmap when drawing in software canvas
        sk_sp<SkSurface> surface; //used only by Skia pipelines
        bool dirty = true;
    };

+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "renderthread/CanvasContext.h"
#include "VectorDrawable.h"
#include "DumpOpsCanvas.h"
#include "SkiaPipeline.h"

#include <SkImagePriv.h>

@@ -92,6 +93,8 @@ bool SkiaDisplayList::prepareListAndChildren(TreeObserver& observer, TreeInfo& i
        // If any vector drawable in the display list needs update, damage the node.
        if (vectorDrawable->isDirty()) {
            isDirty = true;
            static_cast<SkiaPipeline*>(info.canvasContext.getRenderPipeline())
                ->getVectorDrawables()->push_back(vectorDrawable);
        }
        vectorDrawable->setPropertyChangeWillBeConsumed(true);
    }
+30 −1
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <SkPictureRecorder.h>
#include <SkPixelSerializer.h>
#include <SkStream.h>
#include "VectorDrawable.h"

#include <unistd.h>

@@ -40,7 +41,9 @@ uint8_t SkiaPipeline::mSpotShadowAlpha = 0;

Vector3 SkiaPipeline::mLightCenter = {FLT_MIN, FLT_MIN, FLT_MIN};

SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) { }
SkiaPipeline::SkiaPipeline(RenderThread& thread) :  mRenderThread(thread) {
    mVectorDrawables.reserve(30);
}

TaskManager* SkiaPipeline::getTaskManager() {
    return &mTaskManager;
@@ -74,6 +77,7 @@ void SkiaPipeline::renderLayers(const FrameBuilder::LightGeometry& lightGeometry
        const BakedOpRenderer::LightInfo& lightInfo) {
    updateLighting(lightGeometry, lightInfo);
    ATRACE_NAME("draw layers");
    renderVectorDrawableCache();
    renderLayersImpl(*layerUpdateQueue, opaque);
    layerUpdateQueue->clear();
}
@@ -176,10 +180,35 @@ public:
    }
};

void SkiaPipeline::renderVectorDrawableCache() {
    //render VectorDrawables into offscreen buffers
    for (auto vd : mVectorDrawables) {
        sk_sp<SkSurface> surface;
        if (!vd->canReuseSurface()) {
#ifndef ANDROID_ENABLE_LINEAR_BLENDING
            sk_sp<SkColorSpace> colorSpace = nullptr;
#else
            sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
#endif
            int scaledWidth = SkScalarCeilToInt(vd->properties().getScaledWidth());
            int scaledHeight = SkScalarCeilToInt(vd->properties().getScaledHeight());
            SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight,
                    kPremul_SkAlphaType, colorSpace);
            SkASSERT(mRenderThread.getGrContext() != nullptr);
            surface = SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
                    info);
        }
        vd->updateCache(surface);
    }
    mVectorDrawables.clear();
}

void SkiaPipeline::renderFrame(const LayerUpdateQueue& layers, const SkRect& clip,
        const std::vector<sp<RenderNode>>& nodes, bool opaque, const Rect &contentDrawBounds,
        sk_sp<SkSurface> surface) {

    renderVectorDrawableCache();

    // draw all layers up front
    renderLayersImpl(layers, opaque);

+12 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ public:
            const std::vector< sp<RenderNode> >& nodes, bool opaque, const Rect &contentDrawBounds,
            sk_sp<SkSurface> surface);

    std::vector<VectorDrawableRoot*>* getVectorDrawables() { return &mVectorDrawables; }

    static void destroyLayer(RenderNode* node);

    static void prepareToDraw(const renderthread::RenderThread& thread, Bitmap* bitmap);
@@ -119,8 +121,18 @@ private:
            const std::vector< sp<RenderNode> >& nodes, const Rect &contentDrawBounds,
            sk_sp<SkSurface>);

    /**
     *  Render mVectorDrawables into offscreen buffers.
     */
    void renderVectorDrawableCache();

    TaskManager mTaskManager;
    std::vector<sk_sp<SkImage>> mPinnedImages;

    /**
     *  populated by prepareTree with dirty VDs
     */
    std::vector<VectorDrawableRoot*> mVectorDrawables;
    static float mLightRadius;
    static uint8_t mAmbientShadowAlpha;
    static uint8_t mSpotShadowAlpha;
Loading