1 /*
2  * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
3  * Not a Contribution.
4  *
5  * Copyright 2015 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #include "EGLImageBuffer.h"
21 #include <cutils/native_handle.h>
22 #include <gralloc_priv.h>
23 #include <ui/GraphicBuffer.h>
24 #include <map>
25 #include "EGLImageWrapper.h"
26 #include "glengine.h"
27 #define EGL_PROTECTED_CONTENT_EXT 0x32C0
28 
29 //-----------------------------------------------------------------------------
create_eglImage(android::sp<android::GraphicBuffer> graphicBuffer)30 EGLImageKHR create_eglImage(android::sp<android::GraphicBuffer> graphicBuffer)
31 //-----------------------------------------------------------------------------
32 {
33   bool isProtected = (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED);
34   EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
35                     isProtected ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
36                     isProtected ? EGL_TRUE : EGL_NONE, EGL_NONE};
37 
38   EGLImageKHR eglImage = eglCreateImageKHR(
39       eglGetCurrentDisplay(), (EGLContext)EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
40       (EGLClientBuffer)(graphicBuffer->getNativeBuffer()), attrs);
41 
42   return eglImage;
43 }
44 
45 //-----------------------------------------------------------------------------
EGLImageBuffer(android::sp<android::GraphicBuffer> graphicBuffer)46 EGLImageBuffer::EGLImageBuffer(android::sp<android::GraphicBuffer> graphicBuffer)
47 //-----------------------------------------------------------------------------
48 {
49   // this->graphicBuffer = graphicBuffer;
50   this->eglImageID = create_eglImage(graphicBuffer);
51   this->width = graphicBuffer->getWidth();
52   this->height = graphicBuffer->getHeight();
53 
54   textureID = 0;
55   renderbufferID = 0;
56   framebufferID = 0;
57 }
58 
59 //-----------------------------------------------------------------------------
~EGLImageBuffer()60 EGLImageBuffer::~EGLImageBuffer()
61 //-----------------------------------------------------------------------------
62 {
63   if (textureID != 0) {
64     GL(glDeleteTextures(1, &textureID));
65     textureID = 0;
66   }
67 
68   if (renderbufferID != 0) {
69     GL(glDeleteRenderbuffers(1, &renderbufferID));
70     renderbufferID = 0;
71   }
72 
73   if (framebufferID != 0) {
74     GL(glDeleteFramebuffers(1, &framebufferID));
75     framebufferID = 0;
76   }
77 
78   // Delete the eglImage
79   if (eglImageID != 0)
80   {
81       eglDestroyImageKHR(eglGetCurrentDisplay(), eglImageID);
82       eglImageID = 0;
83   }
84 }
85 
86 //-----------------------------------------------------------------------------
getWidth()87 int EGLImageBuffer::getWidth()
88 //-----------------------------------------------------------------------------
89 {
90   return width;
91 }
92 
93 //-----------------------------------------------------------------------------
getHeight()94 int EGLImageBuffer::getHeight()
95 //-----------------------------------------------------------------------------
96 {
97   return height;
98 }
99 
100 //-----------------------------------------------------------------------------
getTexture()101 unsigned int EGLImageBuffer::getTexture()
102 //-----------------------------------------------------------------------------
103 {
104   if (textureID == 0) {
105     bindAsTexture();
106   }
107 
108   return textureID;
109 }
110 
111 //-----------------------------------------------------------------------------
getFramebuffer()112 unsigned int EGLImageBuffer::getFramebuffer()
113 //-----------------------------------------------------------------------------
114 {
115   if (framebufferID == 0) {
116     bindAsFramebuffer();
117   }
118 
119   return framebufferID;
120 }
121 
122 //-----------------------------------------------------------------------------
bindAsTexture()123 void EGLImageBuffer::bindAsTexture()
124 //-----------------------------------------------------------------------------
125 {
126   if (textureID == 0) {
127     GL(glGenTextures(1, &textureID));
128     int target = 0x8D65;
129     GL(glBindTexture(target, textureID));
130     GL(glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
131     GL(glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
132     GL(glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
133     GL(glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
134 
135     GL(glEGLImageTargetTexture2DOES(0x8D65, eglImageID));
136   }
137 
138   GL(glBindTexture(0x8D65, textureID));
139 }
140 
141 //-----------------------------------------------------------------------------
bindAsFramebuffer()142 void EGLImageBuffer::bindAsFramebuffer()
143 //-----------------------------------------------------------------------------
144 {
145   if (renderbufferID == 0) {
146     GL(glGenFramebuffers(1, &framebufferID));
147     GL(glGenRenderbuffers(1, &renderbufferID));
148 
149     GL(glBindRenderbuffer(GL_RENDERBUFFER, renderbufferID));
150     GL(glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, eglImageID));
151 
152     GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferID));
153     GL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
154                                  renderbufferID));
155     GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
156     if (result != GL_FRAMEBUFFER_COMPLETE) {
157       ALOGI("%s Framebuffer Invalid***************", __FUNCTION__);
158     }
159   }
160 
161   GL(glBindFramebuffer(GL_FRAMEBUFFER, framebufferID));
162 }
163