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

Commit 401ef83b authored by Chia-I Wu's avatar Chia-I Wu
Browse files

surfaceflinger: add image abstraction to RenderEngine

Similar to Surface, Image manages the creation and destruction of an
EGLImageKHR.

Test: builds
Change-Id: I2ca98e99013f0a4028f0ea5036f37b20fd67d956
parent 767fcf7e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ LOCAL_SRC_FILES := \
    EventLog/EventLogTags.logtags \
    EventLog/EventLog.cpp \
    RenderEngine/Description.cpp \
    RenderEngine/Image.cpp \
    RenderEngine/Mesh.cpp \
    RenderEngine/Program.cpp \
    RenderEngine/ProgramCache.cpp \
+7 −0
Original line number Diff line number Diff line
@@ -99,6 +99,13 @@ void GLExtensions::initWithEGLStrings(char const* eglVersion, char const* eglExt
    if (hasEGLExtension("EGL_KHR_wait_sync")) {
        mHasWaitSync = true;
    }

    if (hasEGLExtension("EGL_ANDROID_image_crop")) {
        mHasImageCrop = true;
    }
    if (hasEGLExtension("EGL_EXT_protected_content")) {
        mHasProtectedContent = true;
    }
}

char const* GLExtensions::getEGLVersion() const {
+4 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ class GLExtensions : public Singleton<GLExtensions> {
    bool mHasNativeFenceSync = false;
    bool mHasFenceSync = false;
    bool mHasWaitSync = false;
    bool mHasImageCrop = false;
    bool mHasProtectedContent = false;

    String8 mVendor;
    String8 mRenderer;
@@ -63,6 +65,8 @@ public:
    bool hasNativeFenceSync() const { return mHasNativeFenceSync; }
    bool hasFenceSync() const { return mHasFenceSync; }
    bool hasWaitSync() const { return mHasWaitSync; }
    bool hasImageCrop() const { return mHasImageCrop; }
    bool hasProtectedContent() const { return mHasProtectedContent; }

    void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version,
                           GLubyte const* extensions);
+87 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Image.h"

#include <vector>

#include <log/log.h>

#include "GLExtensions.h"
#include "RenderEngine.h"

namespace android {
namespace RE {

Image::Image(const RenderEngine& engine) : mEGLDisplay(engine.getEGLDisplay()) {}

Image::~Image() {
    setNativeWindowBuffer(nullptr, false, 0, 0);
}

static std::vector<EGLint> buildAttributeList(bool isProtected, int32_t cropWidth,
                                              int32_t cropHeight) {
    std::vector<EGLint> attrs;
    attrs.reserve(16);

    attrs.push_back(EGL_IMAGE_PRESERVED_KHR);
    attrs.push_back(EGL_TRUE);

    if (isProtected && GLExtensions::getInstance().hasProtectedContent()) {
        attrs.push_back(EGL_PROTECTED_CONTENT_EXT);
        attrs.push_back(EGL_TRUE);
    }

    if (cropWidth > 0 && cropHeight > 0) {
        attrs.push_back(EGL_IMAGE_CROP_LEFT_ANDROID);
        attrs.push_back(0);
        attrs.push_back(EGL_IMAGE_CROP_TOP_ANDROID);
        attrs.push_back(0);
        attrs.push_back(EGL_IMAGE_CROP_RIGHT_ANDROID);
        attrs.push_back(cropWidth);
        attrs.push_back(EGL_IMAGE_CROP_BOTTOM_ANDROID);
        attrs.push_back(cropHeight);
    }

    attrs.push_back(EGL_NONE);

    return attrs;
}

bool Image::setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, int32_t cropWidth,
                                  int32_t cropHeight) {
    if (mEGLImage != EGL_NO_IMAGE_KHR) {
        if (!eglDestroyImageKHR(mEGLDisplay, mEGLImage)) {
            ALOGE("failed to destroy image: %#x", eglGetError());
        }
        mEGLImage = EGL_NO_IMAGE_KHR;
    }

    if (buffer) {
        std::vector<EGLint> attrs = buildAttributeList(isProtected, cropWidth, cropHeight);
        mEGLImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
                                      static_cast<EGLClientBuffer>(buffer), attrs.data());
        if (mEGLImage == EGL_NO_IMAGE_KHR) {
            ALOGE("failed to create EGLImage: %#x", eglGetError());
            return false;
        }
    }

    return true;
}

} // namespace RE
} // namespace android
+53 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <cstdint>

#include <EGL/egl.h>
#include <EGL/eglext.h>

struct ANativeWindowBuffer;

namespace android {

class RenderEngine;

namespace RE {

class Image {
public:
    Image(const RenderEngine& engine);
    ~Image();

    Image(const Image&) = delete;
    Image& operator=(const Image&) = delete;

    bool setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, int32_t cropWidth,
                               int32_t cropHeight);

private:
    // methods internal to RenderEngine
    friend class android::RenderEngine;
    EGLSurface getEGLImage() const { return mEGLImage; }

    EGLDisplay mEGLDisplay;
    EGLImageKHR mEGLImage = EGL_NO_IMAGE_KHR;
};

} // namespace RE
} // namespace android
Loading