1 /*
2 * Copyright (c) 2021-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
16 #include "rs_surface_ohos_gl.h"
17 #include "platform/common/rs_log.h"
18 #include "window.h"
19 #include <hilog/log.h>
20 #include "pipeline/rs_render_thread.h"
21
22 namespace OHOS {
23 namespace Rosen {
24
RSSurfaceOhosGl(const sptr<Surface> & producer)25 RSSurfaceOhosGl::RSSurfaceOhosGl(const sptr<Surface>& producer) : RSSurfaceOhos(producer)
26 {
27 bufferUsage_ = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_MEM_DMA;
28 }
29
SetSurfaceBufferUsage(uint64_t usage)30 void RSSurfaceOhosGl::SetSurfaceBufferUsage(uint64_t usage)
31 {
32 bufferUsage_ = usage;
33 }
34
SetSurfacePixelFormat(int32_t pixelFormat)35 void RSSurfaceOhosGl::SetSurfacePixelFormat(int32_t pixelFormat)
36 {
37 pixelFormat_ = pixelFormat;
38 }
39
~RSSurfaceOhosGl()40 RSSurfaceOhosGl::~RSSurfaceOhosGl()
41 {
42 if (context_ != nullptr) {
43 context_->DestroyEGLSurface(mEglSurface);
44 }
45 DestoryNativeWindow(mWindow);
46 mWindow = nullptr;
47 mEglSurface = EGL_NO_SURFACE;
48 }
49
RequestFrame(int32_t width,int32_t height,uint64_t uiTimestamp,bool useAFBC,bool isProtected)50 std::unique_ptr<RSSurfaceFrame> RSSurfaceOhosGl::RequestFrame(int32_t width, int32_t height,
51 uint64_t uiTimestamp, bool useAFBC, bool isProtected)
52 {
53 RenderContext* context = GetRenderContext();
54 if (context == nullptr) {
55 ROSEN_LOGE("RSSurfaceOhosGl::RequestFrame, GetRenderContext failed!");
56 return nullptr;
57 }
58 context->SetColorSpace(colorSpace_);
59 context->SetPixelFormat(pixelFormat_);
60 if (mWindow == nullptr) {
61 mWindow = CreateNativeWindowFromSurface(&producer_);
62 mEglSurface = context->CreateEGLSurface((EGLNativeWindowType)mWindow);
63 ROSEN_LOGD("RSSurfaceOhosGl: create and Init EglSurface");
64 }
65
66 if (mEglSurface == EGL_NO_SURFACE) {
67 ROSEN_LOGE("RSSurfaceOhosGl: Invalid eglSurface, return");
68 return nullptr;
69 }
70
71 std::unique_ptr<RSSurfaceFrameOhosGl> frame = std::make_unique<RSSurfaceFrameOhosGl>(width, height);
72
73 NativeWindowHandleOpt(mWindow, SET_FORMAT, pixelFormat_);
74 #ifdef RS_ENABLE_AFBC
75 if (RSSystemProperties::GetAFBCEnabled()) {
76 int32_t format = 0;
77 NativeWindowHandleOpt(mWindow, GET_FORMAT, &format);
78 if (format == GRAPHIC_PIXEL_FMT_RGBA_8888 && useAFBC) {
79 bufferUsage_ =
80 (BUFFER_USAGE_HW_RENDER | BUFFER_USAGE_HW_TEXTURE | BUFFER_USAGE_HW_COMPOSER | BUFFER_USAGE_MEM_DMA);
81 }
82 }
83 #endif
84 NativeWindowHandleOpt(mWindow, SET_USAGE, bufferUsage_);
85 NativeWindowHandleOpt(mWindow, SET_BUFFER_GEOMETRY, width, height);
86 NativeWindowHandleOpt(mWindow, GET_BUFFER_GEOMETRY, &mHeight, &mWidth);
87 NativeWindowHandleOpt(mWindow, SET_COLOR_GAMUT, colorSpace_);
88 NativeWindowHandleOpt(mWindow, SET_UI_TIMESTAMP, uiTimestamp);
89
90 context->MakeCurrent(mEglSurface);
91
92 ROSEN_LOGD("RSSurfaceOhosGl:RequestFrame, width is %d, height is %d",
93 mWidth, mHeight);
94
95 frame->SetRenderContext(context);
96
97 std::unique_ptr<RSSurfaceFrame> ret(std::move(frame));
98
99 return ret;
100 }
101
SetUiTimeStamp(const std::unique_ptr<RSSurfaceFrame> & frame,uint64_t uiTimestamp)102 void RSSurfaceOhosGl::SetUiTimeStamp(const std::unique_ptr<RSSurfaceFrame>& frame, uint64_t uiTimestamp)
103 {
104 struct timespec curTime = {0, 0};
105 clock_gettime(CLOCK_MONOTONIC, &curTime);
106 // 1000000000 is used for transfer second to nsec
107 uint64_t duration = static_cast<uint64_t>(curTime.tv_sec) * 1000000000 + static_cast<uint64_t>(curTime.tv_nsec);
108 NativeWindowHandleOpt(mWindow, SET_UI_TIMESTAMP, duration);
109 }
110
FlushFrame(std::unique_ptr<RSSurfaceFrame> & frame,uint64_t uiTimestamp)111 bool RSSurfaceOhosGl::FlushFrame(std::unique_ptr<RSSurfaceFrame>& frame, uint64_t uiTimestamp)
112 {
113 RenderContext* context = GetRenderContext();
114 if (context == nullptr) {
115 ROSEN_LOGE("RSSurfaceOhosGl::FlushFrame, GetRenderContext failed!");
116 return false;
117 }
118
119 // gpu render flush
120 context->RenderFrame();
121 context->SwapBuffers(mEglSurface);
122 ROSEN_LOGD("RSSurfaceOhosGl: FlushFrame, SwapBuffers eglsurface");
123 return true;
124 }
125
ClearBuffer()126 void RSSurfaceOhosGl::ClearBuffer()
127 {
128 if (context_ != nullptr && mEglSurface != EGL_NO_SURFACE && producer_ != nullptr) {
129 ROSEN_LOGD("RSSurfaceOhosGl: Clear surface buffer!");
130 DestoryNativeWindow(mWindow);
131 context_->MakeCurrent(EGL_NO_SURFACE);
132 context_->DestroyEGLSurface(mEglSurface);
133 mEglSurface = EGL_NO_SURFACE;
134 mWindow = nullptr;
135 producer_->GoBackground();
136 }
137 }
138
ResetBufferAge()139 void RSSurfaceOhosGl::ResetBufferAge()
140 {
141 if (context_ != nullptr && mEglSurface != EGL_NO_SURFACE && producer_ != nullptr) {
142 ROSEN_LOGD("RSSurfaceOhosGl: Reset Buffer Age!");
143 DestoryNativeWindow(mWindow);
144 context_->MakeCurrent(EGL_NO_SURFACE, context_->GetEGLContext());
145 context_->DestroyEGLSurface(mEglSurface);
146 mEglSurface = EGL_NO_SURFACE;
147 mWindow = nullptr;
148 }
149 }
150 } // namespace Rosen
151 } // namespace OHOS
152