Merge "Do not map protected buffers to GPU resources and cache the result" into sc-dev
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index d221a58..540e36a 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -366,6 +366,10 @@
     return mProtectedEGLContext != EGL_NO_CONTEXT;
 }
 
+GrDirectContext* SkiaGLRenderEngine::getActiveGrContext() const {
+    return mInProtectedContext ? mProtectedGrContext.get() : mGrContext.get();
+}
+
 bool SkiaGLRenderEngine::useProtectedContext(bool useProtectedContext) {
     if (useProtectedContext == mInProtectedContext) {
         return true;
@@ -373,6 +377,12 @@
     if (useProtectedContext && !supportsProtectedContent()) {
         return false;
     }
+
+    // release any scratch resources before switching into a new mode
+    if (getActiveGrContext()) {
+        getActiveGrContext()->purgeUnlockedResources(true);
+    }
+
     const EGLSurface surface =
             useProtectedContext ? mProtectedPlaceholderSurface : mPlaceholderSurface;
     const EGLContext context = useProtectedContext ? mProtectedEGLContext : mEGLContext;
@@ -380,6 +390,11 @@
 
     if (success) {
         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;
 }
@@ -490,18 +505,23 @@
     if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) {
         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();
 
     // 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.
     const bool protectedContextState = mInProtectedContext;
-    if (!useProtectedContext(protectedContextState ||
-                             (buffer->getUsage() & GRALLOC_USAGE_PROTECTED))) {
+    if (!useProtectedContext(protectedContextState || isProtectedBuffer)) {
         ALOGE("Attempting to cache a buffer into a different context than what is currently bound");
         return;
     }
 
-    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
+    auto grContext = getActiveGrContext();
     auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
 
     std::lock_guard<std::mutex> lock(mRenderingMutex);
@@ -509,7 +529,7 @@
 
     if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
         std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
-                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
+                std::make_shared<AutoBackendTexture::LocalRef>(grContext,
                                                                buffer->toAHardwareBuffer(),
                                                                isRenderable);
         cache.insert({buffer->getId(), imageTextureRef});
@@ -706,7 +726,7 @@
 
     validateOutputBufferUsage(buffer->getBuffer());
 
-    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
+    auto grContext = getActiveGrContext();
     auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache;
 
     std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef;
@@ -714,14 +734,15 @@
         surfaceTextureRef = it->second;
     } else {
         surfaceTextureRef =
-                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
-                      buffer->getBuffer()->toAHardwareBuffer(), true);
+                std::make_shared<AutoBackendTexture::LocalRef>(grContext,
+                                                               buffer->getBuffer()
+                                                                       ->toAHardwareBuffer(),
+                                                               true);
     }
 
     const ui::Dataspace dstDataspace =
             mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;
-    sk_sp<SkSurface> dstSurface =
-            surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext.get());
+    sk_sp<SkSurface> dstSurface = surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext);
 
     SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
     if (dstCanvas == nullptr) {
@@ -875,8 +896,8 @@
                 if (layer->backgroundBlurRadius > 0) {
                     ATRACE_NAME("BackgroundBlur");
                     auto blurredImage =
-                            mBlurFilter->generate(grContext.get(), layer->backgroundBlurRadius,
-                                                  blurInput, blurRect);
+                            mBlurFilter->generate(grContext, layer->backgroundBlurRadius, blurInput,
+                                                  blurRect);
 
                     cachedBlurs[layer->backgroundBlurRadius] = blurredImage;
 
@@ -889,7 +910,7 @@
                     if (cachedBlurs[region.blurRadius] == nullptr) {
                         ATRACE_NAME("BlurRegion");
                         cachedBlurs[region.blurRadius] =
-                                mBlurFilter->generate(grContext.get(), region.blurRadius, blurInput,
+                                mBlurFilter->generate(grContext, region.blurRadius, blurInput,
                                                       blurRect);
                     }
 
@@ -947,7 +968,7 @@
                 // we didn't find anything in the cache then we intentionally did not cache this
                 // buffer's resources.
                 imageTextureRef = std::make_shared<
-                        AutoBackendTexture::LocalRef>(grContext.get(),
+                        AutoBackendTexture::LocalRef>(grContext,
                                                       item.buffer->getBuffer()->toAHardwareBuffer(),
                                                       false);
             }
@@ -956,7 +977,7 @@
                     imageTextureRef->makeImage(layerDataspace,
                                                item.usePremultipliedAlpha ? kPremul_SkAlphaType
                                                                           : kUnpremul_SkAlphaType,
-                                               grContext.get());
+                                               grContext);
 
             auto texMatrix = getSkM44(item.textureTransform).asM33();
             // textureTansform was intended to be passed directly into a shader, so when
@@ -1341,13 +1362,11 @@
     const int maxResourceBytes = size.width * size.height * SURFACE_SIZE_MULTIPLIER;
 
     // start by resizing the current context
-    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
-    grContext->setResourceCacheLimit(maxResourceBytes);
+    getActiveGrContext()->setResourceCacheLimit(maxResourceBytes);
 
     // if it is possible to switch contexts then we will resize the other context
     if (useProtectedContext(!mInProtectedContext)) {
-        grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
-        grContext->setResourceCacheLimit(maxResourceBytes);
+        getActiveGrContext()->setResourceCacheLimit(maxResourceBytes);
         // reset back to the initial context that was active when this method was called
         useProtectedContext(!mInProtectedContext);
     }
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 3f5591a..d9caf35 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -93,6 +93,7 @@
     inline SkColor getSkColor(const vec4& color);
     inline SkM44 getSkM44(const mat4& matrix);
     inline SkPoint3 getSkPoint3(const vec3& vector);
+    inline GrDirectContext* getActiveGrContext() const;
 
     base::unique_fd flush();
     bool waitFence(base::unique_fd fenceFd);