Home | History | Annotate | Download | only in RenderEngine
      1 /*
      2  * Copyright 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "Image.h"
     18 
     19 #include <vector>
     20 
     21 #include <log/log.h>
     22 
     23 #include "GLExtensions.h"
     24 #include "RenderEngine.h"
     25 
     26 namespace android {
     27 namespace RE {
     28 
     29 Image::~Image() = default;
     30 
     31 namespace impl {
     32 
     33 Image::Image(const RenderEngine& engine) : mEGLDisplay(engine.getEGLDisplay()) {}
     34 
     35 Image::~Image() {
     36     setNativeWindowBuffer(nullptr, false, 0, 0);
     37 }
     38 
     39 static std::vector<EGLint> buildAttributeList(bool isProtected, int32_t cropWidth,
     40                                               int32_t cropHeight) {
     41     std::vector<EGLint> attrs;
     42     attrs.reserve(16);
     43 
     44     attrs.push_back(EGL_IMAGE_PRESERVED_KHR);
     45     attrs.push_back(EGL_TRUE);
     46 
     47     if (isProtected && GLExtensions::getInstance().hasProtectedContent()) {
     48         attrs.push_back(EGL_PROTECTED_CONTENT_EXT);
     49         attrs.push_back(EGL_TRUE);
     50     }
     51 
     52     if (cropWidth > 0 && cropHeight > 0) {
     53         attrs.push_back(EGL_IMAGE_CROP_LEFT_ANDROID);
     54         attrs.push_back(0);
     55         attrs.push_back(EGL_IMAGE_CROP_TOP_ANDROID);
     56         attrs.push_back(0);
     57         attrs.push_back(EGL_IMAGE_CROP_RIGHT_ANDROID);
     58         attrs.push_back(cropWidth);
     59         attrs.push_back(EGL_IMAGE_CROP_BOTTOM_ANDROID);
     60         attrs.push_back(cropHeight);
     61     }
     62 
     63     attrs.push_back(EGL_NONE);
     64 
     65     return attrs;
     66 }
     67 
     68 bool Image::setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected, int32_t cropWidth,
     69                                   int32_t cropHeight) {
     70     if (mEGLImage != EGL_NO_IMAGE_KHR) {
     71         if (!eglDestroyImageKHR(mEGLDisplay, mEGLImage)) {
     72             ALOGE("failed to destroy image: %#x", eglGetError());
     73         }
     74         mEGLImage = EGL_NO_IMAGE_KHR;
     75     }
     76 
     77     if (buffer) {
     78         std::vector<EGLint> attrs = buildAttributeList(isProtected, cropWidth, cropHeight);
     79         mEGLImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
     80                                       static_cast<EGLClientBuffer>(buffer), attrs.data());
     81         if (mEGLImage == EGL_NO_IMAGE_KHR) {
     82             ALOGE("failed to create EGLImage: %#x", eglGetError());
     83             return false;
     84         }
     85     }
     86 
     87     return true;
     88 }
     89 
     90 } // namespace impl
     91 } // namespace RE
     92 } // namespace android
     93