• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "gles_gfx_image.h"
16 #include "window.h"
17 #include "egl_ext_function.h"
18 #include "display_common.h"
19 #include "hardware_buffer.h"
20 #include "display_bytrace.h"
21 #include "display_utils.h"
22 namespace OHOS {
23 namespace HDI {
24 namespace DISPLAY {
GlesGfxImage(EGLDisplay display)25 GlesGfxImage::GlesGfxImage(EGLDisplay display) : eglDisplay_(display)
26 {
27     DISPLAY_LOGD();
28 }
29 
~GlesGfxImage()30 GlesGfxImage::~GlesGfxImage()
31 {
32     DISPLAY_LOGD();
33     for (uint32_t i = 0; i < TEXTURE_COUNT; i++) {
34         if (textureId_[i] != 0) {
35             glDeleteTextures(1, &textureId_[i]);
36         }
37     }
38     if (eglImageKHr_ != EGL_NO_IMAGE_KHR) {
39         EglExtFunction::getInstance().eglDestroyImageKHR(eglDisplay_, eglImageKHr_);
40     }
41 }
42 
Creat(EGLDisplay display,const BufferHandle & bufferHandle)43 std::unique_ptr<GlesGfxImage> GlesGfxImage::Creat(EGLDisplay display, const BufferHandle &bufferHandle)
44 {
45     DISPLAY_LOGD();
46     DisplayBytrace trace("GlesGfxImage::Creat");
47     auto image = std::make_unique<GlesGfxImage>(display);
48     if (image->Init(display, bufferHandle)) {
49         return image;
50     }
51     DISPLAY_LOGE("Falied to int gfx image");
52     return nullptr;
53 }
54 
Init(EGLDisplay display,const BufferHandle & bufferHandle)55 bool GlesGfxImage::Init(EGLDisplay display, const BufferHandle &bufferHandle)
56 {
57     DISPLAY_LOGD();
58     eglDisplay_ = display;
59     if (DisplayUtils::IsYuv(static_cast<PixelFormat>(bufferHandle.format))) {
60         return CreateImageYuv(bufferHandle);
61     } else {
62         return CreateImageRgb(bufferHandle);
63     }
64 }
65 
CreateEglImage(EGLDisplay display,const BufferHandle & bufferhandle)66 EGLImage GlesGfxImage::CreateEglImage(EGLDisplay display, const BufferHandle &bufferhandle)
67 {
68     DISPLAY_LOGD();
69     OHOS::sptr<OHOS::SurfaceBuffer> SurfaceBuffer = OHOS::HardwareBuffer::Create(bufferhandle);
70     if (SurfaceBuffer == nullptr) {
71         DISPLAY_LOGE("Failed to create surface buffer");
72         return EGL_NO_IMAGE_KHR;
73     }
74     struct NativeWindowBuffer *nativeWindowBuffer = CreateNativeWindowBufferFromSurfaceBuffer(&SurfaceBuffer);
75     EGLImageKHR img = EglExtFunction::getInstance().eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS,
76         nativeWindowBuffer, 0);
77     if (img == EGL_NO_IMAGE_KHR) {
78         DISPLAY_LOGE("Failed to create Image Khr");
79     }
80     DestoryNativeWindowBuffer(nativeWindowBuffer);
81     return img;
82 }
83 
DestroyEglImage(EGLDisplay display,EGLImageKHR image)84 EGLBoolean GlesGfxImage::DestroyEglImage(EGLDisplay display, EGLImageKHR image)
85 {
86     return EglExtFunction::getInstance().eglDestroyImageKHR(display, image);
87 }
88 
89 
CreateTextures(uint32_t num)90 void GlesGfxImage::CreateTextures(uint32_t num)
91 {
92     DISPLAY_LOGD("CreateTextures");
93     if (num > TEXTURE_COUNT) {
94         DISPLAY_LOGE("the number is error");
95         num = TEXTURE_COUNT;
96     }
97 
98     for (int i = 0; i < num; i++) {
99         glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // todo wether need ?
100         glGenTextures(1, &textureId_[i]);
101         glBindTexture(GL_TEXTURE_2D, textureId_[i]);
102         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
103         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
104         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
105         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
106     }
107 }
108 
CreateImageRgb(const BufferHandle & bufferHandle)109 bool GlesGfxImage::CreateImageRgb(const BufferHandle &bufferHandle)
110 {
111     DISPLAY_LOGD();
112     CreateTextures(1);
113     glActiveTexture(GL_TEXTURE0);
114     glBindTexture(GL_TEXTURE_2D, textureId_[INDEX_RGB_TEXTURE]);
115     OHOS::sptr<OHOS::SurfaceBuffer> SurfaceBuffer = OHOS::HardwareBuffer::Create(bufferHandle);
116     if (SurfaceBuffer == nullptr) {
117         DISPLAY_LOGE("Failed to create surface buffer");
118         return false;
119     }
120     struct NativeWindowBuffer *nativeWindowBuffer = CreateNativeWindowBufferFromSurfaceBuffer(&SurfaceBuffer);
121     EGLImageKHR img = EglExtFunction::getInstance().eglCreateImageKHR(eglDisplay_, EGL_NO_CONTEXT,
122         EGL_NATIVE_BUFFER_OHOS, nativeWindowBuffer, 0);
123     if (img == EGL_NO_IMAGE_KHR) {
124         DISPLAY_LOGE("Failed to create Image Khr");
125     }
126     EglExtFunction::getInstance().glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, img);
127     eglImageKHr_ = img;
128 
129     DestoryNativeWindowBuffer(nativeWindowBuffer);
130     return true;
131 }
132 
CreateImageYuv(const BufferHandle & bufferHandle)133 bool GlesGfxImage::CreateImageYuv(const BufferHandle &bufferHandle)
134 {
135     DISPLAY_LOGD("CreateImageYuv");
136     const uint32_t textureCount = 3;
137     constexpr const uint32_t UV_SCALE = 2;
138     if (bufferHandle.virAddr == nullptr) {
139         DISPLAY_LOGE("Failed to create yuv image for the virtual address is nullptr");
140         return false;
141     }
142 
143     uint8_t *yData = static_cast<uint8_t *>(bufferHandle.virAddr);
144     uint8_t *uData = yData + (bufferHandle.width * bufferHandle.height);                       // reduce the width
145     uint8_t *vData = uData + (bufferHandle.width * bufferHandle.height) / UV_SCALE / UV_SCALE; // reduce the width
146     CreateTextures(textureCount);
147     // for Y
148     glActiveTexture(GL_TEXTURE0);
149     glBindTexture(GL_TEXTURE_2D, textureId_[INDEX_Y_TEXTURE]);
150     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, bufferHandle.width, bufferHandle.height, 0, GL_LUMINANCE,
151         GL_UNSIGNED_BYTE, yData);
152 
153     glActiveTexture(GL_TEXTURE1);
154     glBindTexture(GL_TEXTURE_2D, textureId_[INDEX_U_TEXTURE]);
155     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, bufferHandle.width / UV_SCALE, bufferHandle.height / UV_SCALE, 0,
156         GL_LUMINANCE, GL_UNSIGNED_BYTE, uData);
157 
158     glActiveTexture(GL_TEXTURE2);
159     glBindTexture(GL_TEXTURE_2D, textureId_[INDEX_V_TEXTURE]);
160     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, bufferHandle.width / UV_SCALE, bufferHandle.height / UV_SCALE, 0,
161         GL_LUMINANCE, GL_UNSIGNED_BYTE, vData);
162     return true;
163 }
164 }
165 }
166 }