1 /*
2  * Copyright 2018 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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
18 
19 #include "GLImage.h"
20 
21 #include <vector>
22 
23 #include <gui/DebugEGLImageTracker.h>
24 #include <log/log.h>
25 #include <utils/Trace.h>
26 #include "GLESRenderEngine.h"
27 #include "GLExtensions.h"
28 
29 namespace android {
30 namespace renderengine {
31 namespace gl {
32 
buildAttributeList(bool isProtected)33 static std::vector<EGLint> buildAttributeList(bool isProtected) {
34     std::vector<EGLint> attrs;
35     attrs.reserve(16);
36 
37     attrs.push_back(EGL_IMAGE_PRESERVED_KHR);
38     attrs.push_back(EGL_TRUE);
39 
40     if (isProtected && GLExtensions::getInstance().hasProtectedContent()) {
41         attrs.push_back(EGL_PROTECTED_CONTENT_EXT);
42         attrs.push_back(EGL_TRUE);
43     }
44 
45     attrs.push_back(EGL_NONE);
46 
47     return attrs;
48 }
49 
GLImage(const GLESRenderEngine & engine)50 GLImage::GLImage(const GLESRenderEngine& engine) : mEGLDisplay(engine.getEGLDisplay()) {}
51 
~GLImage()52 GLImage::~GLImage() {
53     setNativeWindowBuffer(nullptr, false);
54 }
55 
setNativeWindowBuffer(ANativeWindowBuffer * buffer,bool isProtected)56 bool GLImage::setNativeWindowBuffer(ANativeWindowBuffer* buffer, bool isProtected) {
57     ATRACE_CALL();
58     if (mEGLImage != EGL_NO_IMAGE_KHR) {
59         if (!eglDestroyImageKHR(mEGLDisplay, mEGLImage)) {
60             ALOGE("failed to destroy image: %#x", eglGetError());
61         }
62         DEBUG_EGL_IMAGE_TRACKER_DESTROY();
63         mEGLImage = EGL_NO_IMAGE_KHR;
64     }
65 
66     if (buffer) {
67         std::vector<EGLint> attrs = buildAttributeList(isProtected);
68         mEGLImage = eglCreateImageKHR(mEGLDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
69                                       static_cast<EGLClientBuffer>(buffer), attrs.data());
70         if (mEGLImage == EGL_NO_IMAGE_KHR) {
71             ALOGE("failed to create EGLImage: %#x", eglGetError());
72             return false;
73         }
74         DEBUG_EGL_IMAGE_TRACKER_CREATE();
75         mProtected = isProtected;
76     }
77 
78     return true;
79 }
80 
81 } // namespace gl
82 } // namespace renderengine
83 } // namespace android
84