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

Commit b24258c1 authored by Derek Sollenberger's avatar Derek Sollenberger
Browse files

Do not map protected buffers to GPU resources and cache the result

This is in line with the older version of RenderEngine and prevents
the device from exhausting its limited protected GPU memory on cached
objects.

This CL also ensures that upon switching to/from a protected context
that the Skia GPU state is properly initialized and any scratch
resources that were being held onto are purged.

Test: atest com.google.android.media.gts.WidevineDashPolicyTests
Bug: 186158883
Bug: 183391755
Change-Id: I31c03a7589feea6f5d2eb244f77b934e1868326d
parent f938c300
Loading
Loading
Loading
Loading
+37 −18
Original line number Original line Diff line number Diff line
@@ -366,6 +366,10 @@ bool SkiaGLRenderEngine::supportsProtectedContent() const {
    return mProtectedEGLContext != EGL_NO_CONTEXT;
    return mProtectedEGLContext != EGL_NO_CONTEXT;
}
}


GrDirectContext* SkiaGLRenderEngine::getActiveGrContext() const {
    return mInProtectedContext ? mProtectedGrContext.get() : mGrContext.get();
}

bool SkiaGLRenderEngine::useProtectedContext(bool useProtectedContext) {
bool SkiaGLRenderEngine::useProtectedContext(bool useProtectedContext) {
    if (useProtectedContext == mInProtectedContext) {
    if (useProtectedContext == mInProtectedContext) {
        return true;
        return true;
@@ -373,6 +377,12 @@ bool SkiaGLRenderEngine::useProtectedContext(bool useProtectedContext) {
    if (useProtectedContext && !supportsProtectedContent()) {
    if (useProtectedContext && !supportsProtectedContent()) {
        return false;
        return false;
    }
    }

    // release any scratch resources before switching into a new mode
    if (getActiveGrContext()) {
        getActiveGrContext()->purgeUnlockedResources(true);
    }

    const EGLSurface surface =
    const EGLSurface surface =
            useProtectedContext ? mProtectedPlaceholderSurface : mPlaceholderSurface;
            useProtectedContext ? mProtectedPlaceholderSurface : mPlaceholderSurface;
    const EGLContext context = useProtectedContext ? mProtectedEGLContext : mEGLContext;
    const EGLContext context = useProtectedContext ? mProtectedEGLContext : mEGLContext;
@@ -380,6 +390,11 @@ bool SkiaGLRenderEngine::useProtectedContext(bool useProtectedContext) {


    if (success) {
    if (success) {
        mInProtectedContext = useProtectedContext;
        mInProtectedContext = useProtectedContext;
        // given that we are sharing the same thread between two GrContexts we need to
        // make sure that the thread state is reset when switching between the two.
        if (getActiveGrContext()) {
            getActiveGrContext()->resetContext();
        }
    }
    }
    return success;
    return success;
}
}
@@ -490,18 +505,23 @@ void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffe
    if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) {
    if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) {
        return;
        return;
    }
    }
    // we currently don't attempt to map a buffer if the buffer contains protected content
    // because GPU resources for protected buffers is much more limited.
    const bool isProtectedBuffer = buffer->getUsage() & GRALLOC_USAGE_PROTECTED;
    if (isProtectedBuffer) {
        return;
    }
    ATRACE_CALL();
    ATRACE_CALL();


    // We need to switch the currently bound context if the buffer is protected but the current
    // We need to switch the currently bound context if the buffer is protected but the current
    // context is not. The current state must then be restored after the buffer is cached.
    // context is not. The current state must then be restored after the buffer is cached.
    const bool protectedContextState = mInProtectedContext;
    const bool protectedContextState = mInProtectedContext;
    if (!useProtectedContext(protectedContextState ||
    if (!useProtectedContext(protectedContextState || isProtectedBuffer)) {
                             (buffer->getUsage() & GRALLOC_USAGE_PROTECTED))) {
        ALOGE("Attempting to cache a buffer into a different context than what is currently bound");
        ALOGE("Attempting to cache a buffer into a different context than what is currently bound");
        return;
        return;
    }
    }


    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
    auto grContext = getActiveGrContext();
    auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
    auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;


    std::lock_guard<std::mutex> lock(mRenderingMutex);
    std::lock_guard<std::mutex> lock(mRenderingMutex);
@@ -509,7 +529,7 @@ void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffe


    if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
    if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
        std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
        std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
                std::make_shared<AutoBackendTexture::LocalRef>(grContext,
                                                               buffer->toAHardwareBuffer(),
                                                               buffer->toAHardwareBuffer(),
                                                               isRenderable);
                                                               isRenderable);
        cache.insert({buffer->getId(), imageTextureRef});
        cache.insert({buffer->getId(), imageTextureRef});
@@ -695,7 +715,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,


    validateOutputBufferUsage(buffer->getBuffer());
    validateOutputBufferUsage(buffer->getBuffer());


    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
    auto grContext = getActiveGrContext();
    auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
    auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;


    std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef;
    std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef;
@@ -703,14 +723,15 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
        surfaceTextureRef = it->second;
        surfaceTextureRef = it->second;
    } else {
    } else {
        surfaceTextureRef =
        surfaceTextureRef =
                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
                std::make_shared<AutoBackendTexture::LocalRef>(grContext,
                      buffer->getBuffer()->toAHardwareBuffer(), true);
                                                               buffer->getBuffer()
                                                                       ->toAHardwareBuffer(),
                                                               true);
    }
    }


    const ui::Dataspace dstDataspace =
    const ui::Dataspace dstDataspace =
            mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;
            mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;
    sk_sp<SkSurface> dstSurface =
    sk_sp<SkSurface> dstSurface = surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext);
            surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext.get());


    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    if (dstCanvas == nullptr) {
    if (dstCanvas == nullptr) {
@@ -857,8 +878,8 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                if (layer->backgroundBlurRadius > 0) {
                if (layer->backgroundBlurRadius > 0) {
                    ATRACE_NAME("BackgroundBlur");
                    ATRACE_NAME("BackgroundBlur");
                    auto blurredImage =
                    auto blurredImage =
                            mBlurFilter->generate(grContext.get(), layer->backgroundBlurRadius,
                            mBlurFilter->generate(grContext, layer->backgroundBlurRadius, blurInput,
                                                  blurInput, blurRect);
                                                  blurRect);


                    cachedBlurs[layer->backgroundBlurRadius] = blurredImage;
                    cachedBlurs[layer->backgroundBlurRadius] = blurredImage;


@@ -871,7 +892,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                    if (cachedBlurs[region.blurRadius] == nullptr) {
                    if (cachedBlurs[region.blurRadius] == nullptr) {
                        ATRACE_NAME("BlurRegion");
                        ATRACE_NAME("BlurRegion");
                        cachedBlurs[region.blurRadius] =
                        cachedBlurs[region.blurRadius] =
                                mBlurFilter->generate(grContext.get(), region.blurRadius, blurInput,
                                mBlurFilter->generate(grContext, region.blurRadius, blurInput,
                                                      blurRect);
                                                      blurRect);
                    }
                    }


@@ -928,7 +949,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                // we didn't find anything in the cache then we intentionally did not cache this
                // we didn't find anything in the cache then we intentionally did not cache this
                // buffer's resources.
                // buffer's resources.
                imageTextureRef = std::make_shared<
                imageTextureRef = std::make_shared<
                        AutoBackendTexture::LocalRef>(grContext.get(),
                        AutoBackendTexture::LocalRef>(grContext,
                                                      item.buffer->getBuffer()->toAHardwareBuffer(),
                                                      item.buffer->getBuffer()->toAHardwareBuffer(),
                                                      false);
                                                      false);
            }
            }
@@ -937,7 +958,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                    imageTextureRef->makeImage(layerDataspace,
                    imageTextureRef->makeImage(layerDataspace,
                                               item.usePremultipliedAlpha ? kPremul_SkAlphaType
                                               item.usePremultipliedAlpha ? kPremul_SkAlphaType
                                                                          : kUnpremul_SkAlphaType,
                                                                          : kUnpremul_SkAlphaType,
                                               grContext.get());
                                               grContext);


            auto texMatrix = getSkM44(item.textureTransform).asM33();
            auto texMatrix = getSkM44(item.textureTransform).asM33();
            // textureTansform was intended to be passed directly into a shader, so when
            // textureTansform was intended to be passed directly into a shader, so when
@@ -1267,13 +1288,11 @@ void SkiaGLRenderEngine::onPrimaryDisplaySizeChanged(ui::Size size) {
    const int maxResourceBytes = size.width * size.height * SURFACE_SIZE_MULTIPLIER;
    const int maxResourceBytes = size.width * size.height * SURFACE_SIZE_MULTIPLIER;


    // start by resizing the current context
    // start by resizing the current context
    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
    getActiveGrContext()->setResourceCacheLimit(maxResourceBytes);
    grContext->setResourceCacheLimit(maxResourceBytes);


    // if it is possible to switch contexts then we will resize the other context
    // if it is possible to switch contexts then we will resize the other context
    if (useProtectedContext(!mInProtectedContext)) {
    if (useProtectedContext(!mInProtectedContext)) {
        grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
        getActiveGrContext()->setResourceCacheLimit(maxResourceBytes);
        grContext->setResourceCacheLimit(maxResourceBytes);
        // reset back to the initial context that was active when this method was called
        // reset back to the initial context that was active when this method was called
        useProtectedContext(!mInProtectedContext);
        useProtectedContext(!mInProtectedContext);
    }
    }
+1 −0
Original line number Original line Diff line number Diff line
@@ -94,6 +94,7 @@ private:
    inline SkColor getSkColor(const vec4& color);
    inline SkColor getSkColor(const vec4& color);
    inline SkM44 getSkM44(const mat4& matrix);
    inline SkM44 getSkM44(const mat4& matrix);
    inline SkPoint3 getSkPoint3(const vec3& vector);
    inline SkPoint3 getSkPoint3(const vec3& vector);
    inline GrDirectContext* getActiveGrContext() const;


    base::unique_fd flush();
    base::unique_fd flush();
    bool waitFence(base::unique_fd fenceFd);
    bool waitFence(base::unique_fd fenceFd);