Add protected context support

So DRM protected content can still be played on SkiaRE

Test: play videos on YT, pull down the shade with blur
Bug: 164223050
Change-Id: Ia12657c41782c175c2ebd7f95775aa09a4597974
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 902348b..097bcb2 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -252,8 +252,8 @@
 
     // initialize the renderer while GL is current
     std::unique_ptr<SkiaGLRenderEngine> engine =
-            std::make_unique<SkiaGLRenderEngine>(args, display, config, ctxt, placeholder,
-                                                 protectedContext, protectedPlaceholder);
+            std::make_unique<SkiaGLRenderEngine>(args, display, ctxt, placeholder, protectedContext,
+                                                 protectedPlaceholder);
 
     ALOGI("OpenGL ES informations:");
     ALOGI("vendor    : %s", extensions.getVendor());
@@ -306,38 +306,52 @@
 }
 
 SkiaGLRenderEngine::SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display,
-                                       EGLConfig config, EGLContext ctxt, EGLSurface placeholder,
+                                       EGLContext ctxt, EGLSurface placeholder,
                                        EGLContext protectedContext, EGLSurface protectedPlaceholder)
       : mEGLDisplay(display),
-        mEGLConfig(config),
         mEGLContext(ctxt),
         mPlaceholderSurface(placeholder),
         mProtectedEGLContext(protectedContext),
         mProtectedPlaceholderSurface(protectedPlaceholder),
         mUseColorManagement(args.useColorManagement) {
-    // Suppress unused field warnings for things we definitely will need/use
-    // These EGL fields will all be needed for toggling between protected & unprotected contexts
-    // Or we need different RE instances for that
-    (void)mEGLDisplay;
-    (void)mEGLConfig;
-    (void)mEGLContext;
-    (void)mPlaceholderSurface;
-    (void)mProtectedEGLContext;
-    (void)mProtectedPlaceholderSurface;
-
     sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
     LOG_ALWAYS_FATAL_IF(!glInterface.get());
 
     GrContextOptions options;
     options.fPreferExternalImagesOverES3 = true;
     options.fDisableDistanceFieldPaths = true;
-    mGrContext = GrDirectContext::MakeGL(std::move(glInterface), options);
+    mGrContext = GrDirectContext::MakeGL(glInterface, options);
+    if (useProtectedContext(true)) {
+        mProtectedGrContext = GrDirectContext::MakeGL(glInterface, options);
+        useProtectedContext(false);
+    }
 
     if (args.supportsBackgroundBlur) {
         mBlurFilter = new BlurFilter();
     }
 }
 
+bool SkiaGLRenderEngine::supportsProtectedContent() const {
+    return mProtectedEGLContext != EGL_NO_CONTEXT;
+}
+
+bool SkiaGLRenderEngine::useProtectedContext(bool useProtectedContext) {
+    if (useProtectedContext == mInProtectedContext) {
+        return true;
+    }
+    if (useProtectedContext && supportsProtectedContent()) {
+        return false;
+    }
+    const EGLSurface surface =
+            useProtectedContext ? mProtectedPlaceholderSurface : mPlaceholderSurface;
+    const EGLContext context = useProtectedContext ? mProtectedEGLContext : mEGLContext;
+    const bool success = eglMakeCurrent(mEGLDisplay, surface, surface, context) == EGL_TRUE;
+    if (success) {
+        mInProtectedContext = useProtectedContext;
+    }
+    return success;
+}
+
 base::unique_fd SkiaGLRenderEngine::flush() {
     ATRACE_CALL();
     if (!gl::GLExtensions::getInstance().hasNativeFenceSync()) {
@@ -471,22 +485,23 @@
         return BAD_VALUE;
     }
 
+    auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext;
+    auto cache = mInProtectedContext ? mProtectedSurfaceCache : mSurfaceCache;
     AHardwareBuffer_Desc bufferDesc;
     AHardwareBuffer_describe(buffer->toAHardwareBuffer(), &bufferDesc);
-
     LOG_ALWAYS_FATAL_IF(!hasUsage(bufferDesc, AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE),
                         "missing usage");
 
     sk_sp<SkSurface> surface;
     if (useFramebufferCache) {
-        auto iter = mSurfaceCache.find(buffer->getId());
-        if (iter != mSurfaceCache.end()) {
+        auto iter = cache.find(buffer->getId());
+        if (iter != cache.end()) {
             ALOGV("Cache hit!");
             surface = iter->second;
         }
     }
     if (!surface) {
-        surface = SkSurface::MakeFromAHardwareBuffer(mGrContext.get(), buffer->toAHardwareBuffer(),
+        surface = SkSurface::MakeFromAHardwareBuffer(grContext.get(), buffer->toAHardwareBuffer(),
                                                      GrSurfaceOrigin::kTopLeft_GrSurfaceOrigin,
                                                      mUseColorManagement
                                                              ? toColorSpace(display.outputDataspace)
@@ -494,7 +509,7 @@
                                                      nullptr);
         if (useFramebufferCache && surface) {
             ALOGD("Adding to cache");
-            mSurfaceCache.insert({buffer->getId(), surface});
+            cache.insert({buffer->getId(), surface});
         }
     }
     if (!surface) {
@@ -699,7 +714,7 @@
     } else {
         ATRACE_BEGIN("Submit(sync=false)");
     }
-    bool success = mGrContext->submit(requireSync);
+    bool success = grContext->submit(requireSync);
     ATRACE_END();
     if (!success) {
         ALOGE("Failed to flush RenderEngine commands");
@@ -868,6 +883,7 @@
 
 void SkiaGLRenderEngine::cleanFramebufferCache() {
     mSurfaceCache.clear();
+    mProtectedSurfaceCache.clear();
 }
 
 } // namespace skia