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
16 #include "native_buffer_inner.h"
17
18 #include <cinttypes>
19 #include "surface_type.h"
20 #include "buffer_log.h"
21 #include "native_window.h"
22 #include "surface_buffer_impl.h"
23 #include "metadata_helper.h"
24
25 using namespace OHOS;
26 using namespace HDI::Display::Graphic::Common::V1_0;
27 static std::unordered_map<OH_NativeBuffer_ColorSpace, CM_ColorSpaceType> NATIVE_COLORSPACE_TO_HDI_MAP = {
28 {OH_COLORSPACE_NONE, CM_COLORSPACE_NONE},
29 {OH_COLORSPACE_BT601_EBU_FULL, CM_BT601_EBU_FULL},
30 {OH_COLORSPACE_BT601_SMPTE_C_FULL, CM_BT601_SMPTE_C_FULL},
31 {OH_COLORSPACE_BT709_FULL, CM_BT709_FULL},
32 {OH_COLORSPACE_BT2020_HLG_FULL, CM_BT2020_HLG_FULL},
33 {OH_COLORSPACE_BT2020_PQ_FULL, CM_BT2020_PQ_FULL},
34 {OH_COLORSPACE_BT601_EBU_LIMIT, CM_BT601_EBU_LIMIT},
35 {OH_COLORSPACE_BT601_SMPTE_C_LIMIT, CM_BT601_SMPTE_C_LIMIT},
36 {OH_COLORSPACE_BT709_LIMIT, CM_BT709_LIMIT},
37 {OH_COLORSPACE_BT2020_HLG_LIMIT, CM_BT2020_HLG_LIMIT},
38 {OH_COLORSPACE_BT2020_PQ_LIMIT, CM_BT2020_PQ_LIMIT},
39 {OH_COLORSPACE_SRGB_FULL, CM_SRGB_FULL},
40 {OH_COLORSPACE_P3_FULL, CM_P3_FULL},
41 {OH_COLORSPACE_P3_HLG_FULL, CM_P3_HLG_FULL},
42 {OH_COLORSPACE_P3_PQ_FULL, CM_P3_PQ_FULL},
43 {OH_COLORSPACE_ADOBERGB_FULL, CM_ADOBERGB_FULL},
44 {OH_COLORSPACE_SRGB_LIMIT, CM_SRGB_LIMIT},
45 {OH_COLORSPACE_P3_LIMIT, CM_P3_LIMIT},
46 {OH_COLORSPACE_P3_HLG_LIMIT, CM_P3_HLG_LIMIT},
47 {OH_COLORSPACE_P3_PQ_LIMIT, CM_P3_PQ_LIMIT},
48 {OH_COLORSPACE_ADOBERGB_LIMIT, CM_ADOBERGB_LIMIT},
49 {OH_COLORSPACE_LINEAR_SRGB, CM_LINEAR_SRGB},
50 {OH_COLORSPACE_LINEAR_BT709, CM_LINEAR_BT709},
51 {OH_COLORSPACE_LINEAR_P3, CM_LINEAR_P3},
52 {OH_COLORSPACE_LINEAR_BT2020, CM_LINEAR_BT2020},
53 {OH_COLORSPACE_DISPLAY_SRGB, CM_DISPLAY_SRGB},
54 {OH_COLORSPACE_DISPLAY_P3_SRGB, CM_DISPLAY_P3_SRGB},
55 {OH_COLORSPACE_DISPLAY_P3_HLG, CM_DISPLAY_P3_HLG},
56 {OH_COLORSPACE_DISPLAY_P3_PQ, CM_DISPLAY_P3_PQ},
57 {OH_COLORSPACE_DISPLAY_BT2020_SRGB, CM_DISPLAY_BT2020_SRGB},
58 {OH_COLORSPACE_DISPLAY_BT2020_HLG, CM_DISPLAY_BT2020_HLG},
59 {OH_COLORSPACE_DISPLAY_BT2020_PQ, CM_DISPLAY_BT2020_PQ}
60 };
61
OH_NativeBufferFromSurfaceBuffer(SurfaceBuffer * buffer)62 static OH_NativeBuffer* OH_NativeBufferFromSurfaceBuffer(SurfaceBuffer* buffer)
63 {
64 return buffer->SurfaceBufferToNativeBuffer();
65 }
66
OH_NativeBufferToSurfaceBuffer(OH_NativeBuffer * buffer)67 static SurfaceBuffer* OH_NativeBufferToSurfaceBuffer(OH_NativeBuffer *buffer)
68 {
69 return SurfaceBuffer::NativeBufferToSurfaceBuffer(buffer);
70 }
71
OH_NativeBufferToSurfaceBuffer(const OH_NativeBuffer * buffer)72 static const SurfaceBuffer* OH_NativeBufferToSurfaceBuffer(const OH_NativeBuffer *buffer)
73 {
74 return SurfaceBuffer::NativeBufferToSurfaceBuffer(buffer);
75 }
76
OH_NativeBuffer_Alloc(const OH_NativeBuffer_Config * config)77 OH_NativeBuffer* OH_NativeBuffer_Alloc(const OH_NativeBuffer_Config* config)
78 {
79 if (config == nullptr) {
80 BLOGE("parameter error, please check input parameter");
81 return nullptr;
82 }
83 BufferRequestConfig bfConfig = {};
84 bfConfig.width = config->width;
85 bfConfig.height = config->height;
86 bfConfig.strideAlignment = 0x8; // set 0x8 as default value to alloc SurfaceBufferImpl
87 bfConfig.format = config->format; // PixelFormat
88 bfConfig.usage = config->usage;
89 bfConfig.timeout = 0;
90 bfConfig.colorGamut = GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB;
91 bfConfig.transform = GraphicTransformType::GRAPHIC_ROTATE_NONE;
92 sptr<SurfaceBuffer> bufferImpl = new SurfaceBufferImpl();
93 GSError ret = bufferImpl->Alloc(bfConfig);
94 if (ret != GSERROR_OK) {
95 BLOGE("Surface Buffer Alloc failed, %{public}s", GSErrorStr(ret).c_str());
96 return nullptr;
97 }
98
99 OH_NativeBuffer* buffer = OH_NativeBufferFromSurfaceBuffer(bufferImpl);
100 int32_t err = OH_NativeBuffer_Reference(buffer);
101 if (err != OHOS::GSERROR_OK) {
102 BLOGE("NativeBufferReference failed");
103 return nullptr;
104 }
105 return buffer;
106 }
107
OH_NativeBuffer_Reference(OH_NativeBuffer * buffer)108 int32_t OH_NativeBuffer_Reference(OH_NativeBuffer *buffer)
109 {
110 if (buffer == nullptr) {
111 BLOGE("parameter error, please check input parameter");
112 return OHOS::GSERROR_INVALID_ARGUMENTS;
113 }
114 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
115 ref->IncStrongRef(ref);
116 return OHOS::GSERROR_OK;
117 }
118
OH_NativeBuffer_Unreference(OH_NativeBuffer * buffer)119 int32_t OH_NativeBuffer_Unreference(OH_NativeBuffer *buffer)
120 {
121 if (buffer == nullptr) {
122 BLOGE("parameter error, please check input parameter");
123 return OHOS::GSERROR_INVALID_ARGUMENTS;
124 }
125 OHOS::RefBase *ref = reinterpret_cast<OHOS::RefBase *>(buffer);
126 ref->DecStrongRef(ref);
127 return OHOS::GSERROR_OK;
128 }
129
OH_NativeBuffer_GetConfig(OH_NativeBuffer * buffer,OH_NativeBuffer_Config * config)130 void OH_NativeBuffer_GetConfig(OH_NativeBuffer *buffer, OH_NativeBuffer_Config* config)
131 {
132 if (buffer == nullptr || config == nullptr) {
133 BLOGE("parameter error, please check input parameter");
134 return;
135 }
136 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
137 config->width = sbuffer->GetWidth();
138 config->height = sbuffer->GetHeight();
139 config->format = sbuffer->GetFormat();
140 config->usage = sbuffer->GetUsage();
141 config->stride = sbuffer->GetStride();
142 }
143
OH_NativeBuffer_Map(OH_NativeBuffer * buffer,void ** virAddr)144 int32_t OH_NativeBuffer_Map(OH_NativeBuffer *buffer, void **virAddr)
145 {
146 if (buffer == nullptr) {
147 BLOGE("parameter error, please check input parameter");
148 return OHOS::GSERROR_INVALID_ARGUMENTS;
149 }
150 SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
151 int32_t ret = sbuffer->Map();
152 if (ret == OHOS::GSERROR_OK) {
153 *virAddr = sbuffer->GetVirAddr();
154 }
155 return ret;
156 }
157
OH_NativeBuffer_Unmap(OH_NativeBuffer * buffer)158 int32_t OH_NativeBuffer_Unmap(OH_NativeBuffer *buffer)
159 {
160 if (buffer == nullptr) {
161 BLOGE("parameter error, please check input parameter");
162 return OHOS::GSERROR_INVALID_ARGUMENTS;
163 }
164 SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
165 return sbuffer->Unmap();
166 }
167
OH_NativeBuffer_GetSeqNum(OH_NativeBuffer * buffer)168 uint32_t OH_NativeBuffer_GetSeqNum(OH_NativeBuffer *buffer)
169 {
170 if (buffer == nullptr) {
171 BLOGE("parameter error, please check input parameter");
172 return OHOS::GSERROR_INVALID_ARGUMENTS;
173 }
174 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
175 return sbuffer->GetSeqNum();
176 }
177
OH_NativeBuffer_GetBufferHandle(const OH_NativeBuffer * buffer)178 const BufferHandle* OH_NativeBuffer_GetBufferHandle(const OH_NativeBuffer *buffer)
179 {
180 if (buffer == nullptr) {
181 BLOGE("parameter error, please check input parameter");
182 return nullptr;
183 }
184 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
185 return sbuffer->GetBufferHandle();
186 }
187
OH_NativeBuffer_GetNativeBufferConfig(const OH_NativeBuffer * buffer,OH_NativeBuffer_Config * config)188 void OH_NativeBuffer_GetNativeBufferConfig(const OH_NativeBuffer *buffer, OH_NativeBuffer_Config* config)
189 {
190 if (buffer == nullptr || config == nullptr) {
191 BLOGE("parameter error, please check input parameter");
192 return;
193 }
194 const SurfaceBuffer* sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
195 config->width = sbuffer->GetWidth();
196 config->height = sbuffer->GetHeight();
197 config->format = sbuffer->GetFormat();
198 config->usage = sbuffer->GetUsage();
199 config->stride = sbuffer->GetStride();
200 }
201
OH_NativeBufferFromNativeWindowBuffer(OHNativeWindowBuffer * nativeWindowBuffer)202 OH_NativeBuffer* OH_NativeBufferFromNativeWindowBuffer(OHNativeWindowBuffer* nativeWindowBuffer)
203 {
204 if (nativeWindowBuffer == nullptr) {
205 BLOGE("parameter error, please check input parameter");
206 return nullptr;
207 }
208 OH_NativeBuffer* buffer = OH_NativeBufferFromSurfaceBuffer(nativeWindowBuffer->sfbuffer);
209 return buffer;
210 }
211
OH_NativeBuffer_SetColorSpace(OH_NativeBuffer * buffer,OH_NativeBuffer_ColorSpace colorSpace)212 int32_t OH_NativeBuffer_SetColorSpace(OH_NativeBuffer *buffer, OH_NativeBuffer_ColorSpace colorSpace)
213 {
214 if (buffer == nullptr || NATIVE_COLORSPACE_TO_HDI_MAP.find(colorSpace) == NATIVE_COLORSPACE_TO_HDI_MAP.end()) {
215 BLOGE("parameter error, please check input parameter");
216 return OHOS::GSERROR_INVALID_ARGUMENTS;
217 }
218 sptr<SurfaceBuffer> sbuffer = OH_NativeBufferToSurfaceBuffer(buffer);
219 GSError ret = MetadataHelper::SetColorSpaceType(sbuffer, NATIVE_COLORSPACE_TO_HDI_MAP[colorSpace]);
220 if (GSErrorStr(ret) == "<500 api call failed>with low error <Not supported>") {
221 return OHOS::GSERROR_NOT_SUPPORT;
222 }
223 return ret;
224 }