Swap contexts when unmapping ExternalTextures

Protected surfaces aren't visible to other contexts even when the
contexts have a shared object space, so the protected context must be
active when freeing protected textures. Otherwise, this may result in a
GPU memory leak.

Bug: 187870007
Bug: 189899352
Test: WidevineHEVCPlaybackTests
Change-Id: Id4d51df1878903a8e638c38c0cfb64527402143b
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index f0986a3..afe88f4 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -552,10 +552,25 @@
 
         iter->second--;
 
+        // Swap contexts if needed prior to deleting this buffer
+        // See Issue 1 of
+        // https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_protected_content.txt: even
+        // when a protected context and an unprotected context are part of the same share group,
+        // protected surfaces may not be accessed by an unprotected context, implying that protected
+        // surfaces may only be freed when a protected context is active.
+        const bool inProtected = mInProtectedContext;
+        useProtectedContext(buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
+
         if (iter->second == 0) {
             mTextureCache.erase(buffer->getId());
             mGraphicBufferExternalRefs.erase(buffer->getId());
         }
+
+        // Swap back to the previous context so that cached values of isProtected in SurfaceFlinger
+        // are up-to-date.
+        if (inProtected != mInProtectedContext) {
+            useProtectedContext(inProtected);
+        }
     }
 }