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

Commit 20c0faaa authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Add protected context support"

parents b8871072 d508e473
Loading
Loading
Loading
Loading
+37 −21
Original line number Diff line number Diff line
@@ -252,8 +252,8 @@ std::unique_ptr<SkiaGLRenderEngine> SkiaGLRenderEngine::create(

    // 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 @@ EGLConfig SkiaGLRenderEngine::chooseEglConfig(EGLDisplay display, int format, bo
}

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 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
        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 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                                                     nullptr);
        if (useFramebufferCache && surface) {
            ALOGD("Adding to cache");
            mSurfaceCache.insert({buffer->getId(), surface});
            cache.insert({buffer->getId(), surface});
        }
    }
    if (!surface) {
@@ -705,7 +720,7 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
    } 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");
@@ -897,6 +912,7 @@ EGLSurface SkiaGLRenderEngine::createPlaceholderEglPbufferSurface(EGLDisplay dis

void SkiaGLRenderEngine::cleanFramebufferCache() {
    mSurfaceCache.clear();
    mProtectedSurfaceCache.clear();
}

} // namespace skia
+10 −3
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ namespace skia {
class SkiaGLRenderEngine : public skia::SkiaRenderEngine {
public:
    static std::unique_ptr<SkiaGLRenderEngine> create(const RenderEngineCreationArgs& args);
    SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, EGLConfig config,
                       EGLContext ctxt, EGLSurface placeholder, EGLContext protectedContext,
    SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGLDisplay display, EGLContext ctxt,
                       EGLSurface placeholder, EGLContext protectedContext,
                       EGLSurface protectedPlaceholder);
    ~SkiaGLRenderEngine() override{};

@@ -51,6 +51,9 @@ public:
                        const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
                        base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
    void cleanFramebufferCache() override;
    bool isProtected() const override { return mInProtectedContext; }
    bool supportsProtectedContent() const override;
    bool useProtectedContext(bool useProtectedContext) override;

protected:
    void dump(std::string& /*result*/) override{};
@@ -81,7 +84,6 @@ private:
                        const SkMatrix& drawTransform, sk_sp<SkSurface> blurrendSurface);

    EGLDisplay mEGLDisplay;
    EGLConfig mEGLConfig;
    EGLContext mEGLContext;
    EGLSurface mPlaceholderSurface;
    EGLContext mProtectedEGLContext;
@@ -100,9 +102,14 @@ private:

    sp<Fence> mLastDrawFence;

    // Graphics context used for creating surfaces and submitting commands
    sk_sp<GrDirectContext> mGrContext;
    // Same as above, but for protected content (eg. DRM)
    sk_sp<GrDirectContext> mProtectedGrContext;

    std::unordered_map<uint64_t, sk_sp<SkSurface>> mSurfaceCache;
    std::unordered_map<uint64_t, sk_sp<SkSurface>> mProtectedSurfaceCache;
    bool mInProtectedContext = false;
};

} // namespace skia