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

Commit 573c453a authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge changes I5cad0b5d,I6863eca2

* changes:
  Render VectorDrawables in software and then upload to the VDAtlas.
  Adding traces and some generic cleanup.
parents 78b69408 7fe53c1e
Loading
Loading
Loading
Loading
+15 −28
Original line number Diff line number Diff line
@@ -511,22 +511,16 @@ void Tree::updateCache(sp<skiapipeline::VectorDrawableAtlas>& atlas, GrContext*
        }
    }
    if (!canReuseSurface || mCache.dirty) {
        draw(surface.get(), dst);
        mCache.dirty = false;
        if (surface) {
            Bitmap& bitmap = getBitmapUpdateIfDirty();
            SkBitmap skiaBitmap;
            bitmap.getSkBitmap(&skiaBitmap);
            if (!surface->getCanvas()->writePixels(skiaBitmap, dst.fLeft, dst.fTop)) {
                ALOGD("VectorDrawable caching failed to efficiently upload");
                surface->getCanvas()->drawBitmap(skiaBitmap, dst.fLeft, dst.fTop);
            }
        }

void Tree::draw(SkSurface* surface, const SkRect& dst) {
    if (surface) {
        SkCanvas* canvas = surface->getCanvas();
        float scaleX = dst.width() / mProperties.getViewportWidth();
        float scaleY = dst.height() / mProperties.getViewportHeight();
        SkAutoCanvasRestore acr(canvas, true);
        canvas->translate(dst.fLeft, dst.fTop);
        canvas->clipRect(SkRect::MakeWH(dst.width(), dst.height()));
        canvas->clear(SK_ColorTRANSPARENT);
        canvas->scale(scaleX, scaleY);
        mRootNode->draw(canvas, false);
        mCache.dirty = false;
    }
}

@@ -570,22 +564,15 @@ void Tree::draw(SkCanvas* canvas) {
        // Handle the case when VectorDrawableAtlas has been destroyed, because of memory pressure.
        // We render the VD into a temporary standalone buffer and mark the frame as dirty. Next
        // frame will be cached into the atlas.
        Bitmap& bitmap = getBitmapUpdateIfDirty();
        SkBitmap skiaBitmap;
        bitmap.getSkBitmap(&skiaBitmap);

        int scaledWidth = SkScalarCeilToInt(mProperties.getScaledWidth());
        int scaledHeight = SkScalarCeilToInt(mProperties.getScaledHeight());
        SkRect src = SkRect::MakeWH(scaledWidth, scaledHeight);
#ifndef ANDROID_ENABLE_LINEAR_BLENDING
        sk_sp<SkColorSpace> colorSpace = nullptr;
#else
        sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
#endif
        SkImageInfo info = SkImageInfo::MakeN32(scaledWidth, scaledHeight, kPremul_SkAlphaType,
                colorSpace);
        sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(canvas->getGrContext(),
                SkBudgeted::kYes, info);
        draw(surface.get(), src);
        canvas->drawBitmapRect(skiaBitmap, SkRect::MakeWH(scaledWidth, scaledHeight),
                        mutateProperties()->getBounds(), getPaint(), SkCanvas::kFast_SrcRectConstraint);
        mCache.clear();
        canvas->drawImageRect(surface->makeImageSnapshot().get(), mutateProperties()->getBounds(),
                getPaint(), SkCanvas::kFast_SrcRectConstraint);
        markDirty();
    }
}
+0 −5
Original line number Diff line number Diff line
@@ -738,11 +738,6 @@ private:
    bool canReuseBitmap(Bitmap*, int width, int height);
    void updateBitmapCache(Bitmap& outCache, bool useStagingData);

    /**
     * Draws the root node into "surface" at a given "dst" position.
     */
    void draw(SkSurface* surface, const SkRect& dst);

    // Cap the bitmap size, such that it won't hurt the performance too much
    // and it won't crash due to a very large scale.
    // The drawable will look blurry above this size.
+3 −2
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ void SkiaPipeline::renderLayersImpl(const LayerUpdateQueue& layers,
                return;
            }

            ATRACE_FORMAT("drawLayer [%s] %.1f x %.1f", layerNode->getName(), bounds.width(), bounds.height());

            layerNode->getSkiaLayer()->hasRenderedSinceRepaint = false;
            layerCanvas->clear(SK_ColorTRANSPARENT);

@@ -143,7 +145,6 @@ bool SkiaPipeline::createOrUpdateLayer(RenderNode* node,
        }
        SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
        SkASSERT(mRenderThread.getGrContext() != nullptr);
        // TODO: Handle wide color gamut requests
        node->setLayerSurface(
                SkSurface::MakeRenderTarget(mRenderThread.getGrContext(), SkBudgeted::kYes,
                        info, 0, &props));
@@ -194,10 +195,10 @@ void SkiaPipeline::renderVectorDrawableCache() {
        sp<VectorDrawableAtlas> atlas = mRenderThread.cacheManager().acquireVectorDrawableAtlas();
        auto grContext = mRenderThread.getGrContext();
        atlas->prepareForDraw(grContext);
        ATRACE_NAME("Update VectorDrawables");
        for (auto vd : mVectorDrawables) {
            vd->updateCache(atlas, grContext);
        }
        grContext->flush();
        mVectorDrawables.clear();
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -270,7 +270,10 @@ sk_sp<SkSurface> VectorDrawableAtlas::createSurface(int width, int height, GrCon
    sk_sp<SkColorSpace> colorSpace = SkColorSpace::MakeSRGB();
#endif
    SkImageInfo info = SkImageInfo::MakeN32(width, height, kPremul_SkAlphaType, colorSpace);
    return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info);
    // This must have a top-left origin so that calls to surface->canvas->writePixels
    // performs a basic texture upload instead of a more complex drawing operation
    return SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0,
            kTopLeft_GrSurfaceOrigin, nullptr);
}

void VectorDrawableAtlas::setStorageMode(StorageMode mode) {