1e9297d28Sopenharmony_ci/*
2e9297d28Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3e9297d28Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e9297d28Sopenharmony_ci * you may not use this file except in compliance with the License.
5e9297d28Sopenharmony_ci * You may obtain a copy of the License at
6e9297d28Sopenharmony_ci *
7e9297d28Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e9297d28Sopenharmony_ci *
9e9297d28Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e9297d28Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e9297d28Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e9297d28Sopenharmony_ci * See the License for the specific language governing permissions and
13e9297d28Sopenharmony_ci * limitations under the License.
14e9297d28Sopenharmony_ci */
15e9297d28Sopenharmony_ci
16e9297d28Sopenharmony_ci#include "native_image.h"
17e9297d28Sopenharmony_ci#include "surface.h"
18e9297d28Sopenharmony_ci#include "surface_image.h"
19e9297d28Sopenharmony_ci#include "window.h"
20e9297d28Sopenharmony_ci#include "surface_utils.h"
21e9297d28Sopenharmony_ci
22e9297d28Sopenharmony_ciusing namespace OHOS;
23e9297d28Sopenharmony_ci
24e9297d28Sopenharmony_cistruct OH_NativeImage {
25e9297d28Sopenharmony_ci    OHOS::sptr<OHOS::SurfaceImage> consumer = nullptr;
26e9297d28Sopenharmony_ci    OHOS::sptr<OHOS::IBufferProducer> producer = nullptr;
27e9297d28Sopenharmony_ci    OHOS::sptr<OHOS::Surface> pSurface = nullptr;
28e9297d28Sopenharmony_ci    struct NativeWindow* nativeWindow = nullptr;
29e9297d28Sopenharmony_ci};
30e9297d28Sopenharmony_ci
31e9297d28Sopenharmony_ciOH_NativeImage* OH_NativeImage_Create(uint32_t textureId, uint32_t textureTarget)
32e9297d28Sopenharmony_ci{
33e9297d28Sopenharmony_ci    OHOS::sptr<OHOS::SurfaceImage> surfaceImage = new SurfaceImage(textureId, textureTarget);
34e9297d28Sopenharmony_ci    sptr<OHOS::IBufferProducer> producer = surfaceImage->GetProducer();
35e9297d28Sopenharmony_ci    OH_NativeImage* nativeImage = new OH_NativeImage();
36e9297d28Sopenharmony_ci    nativeImage->consumer = surfaceImage;
37e9297d28Sopenharmony_ci    nativeImage->producer = producer;
38e9297d28Sopenharmony_ci    sptr<IBufferConsumerListener> listener = new SurfaceImageListener(surfaceImage);
39e9297d28Sopenharmony_ci    nativeImage->consumer->RegisterConsumerListener(listener);
40e9297d28Sopenharmony_ci    return nativeImage;
41e9297d28Sopenharmony_ci}
42e9297d28Sopenharmony_ci
43e9297d28Sopenharmony_ciOH_NativeImage* OH_ConsumerSurface_Create()
44e9297d28Sopenharmony_ci{
45e9297d28Sopenharmony_ci    OHOS::sptr<OHOS::SurfaceImage> surfaceImage = new SurfaceImage();
46e9297d28Sopenharmony_ci    sptr<OHOS::IBufferProducer> producer = surfaceImage->GetProducer();
47e9297d28Sopenharmony_ci    OH_NativeImage* nativeImage = new OH_NativeImage();
48e9297d28Sopenharmony_ci    nativeImage->consumer = surfaceImage;
49e9297d28Sopenharmony_ci    nativeImage->producer = producer;
50e9297d28Sopenharmony_ci    sptr<IBufferConsumerListener> listener = new SurfaceImageListener(surfaceImage);
51e9297d28Sopenharmony_ci    nativeImage->consumer->RegisterConsumerListener(listener);
52e9297d28Sopenharmony_ci    return nativeImage;
53e9297d28Sopenharmony_ci}
54e9297d28Sopenharmony_ci
55e9297d28Sopenharmony_ciOHNativeWindow* OH_NativeImage_AcquireNativeWindow(OH_NativeImage* image)
56e9297d28Sopenharmony_ci{
57e9297d28Sopenharmony_ci    if (image == nullptr) {
58e9297d28Sopenharmony_ci        BLOGE("parameter error");
59e9297d28Sopenharmony_ci        return nullptr;
60e9297d28Sopenharmony_ci    }
61e9297d28Sopenharmony_ci
62e9297d28Sopenharmony_ci    if (image->nativeWindow == nullptr) {
63e9297d28Sopenharmony_ci        if (image->pSurface == nullptr) {
64e9297d28Sopenharmony_ci            image->pSurface = Surface::CreateSurfaceAsProducer(image->producer);
65e9297d28Sopenharmony_ci        }
66e9297d28Sopenharmony_ci        BLOGE_CHECK_AND_RETURN_RET(image->pSurface != nullptr, nullptr, "pSurface is null");
67e9297d28Sopenharmony_ci        image->nativeWindow = CreateNativeWindowFromSurface(&(image->pSurface));
68e9297d28Sopenharmony_ci    }
69e9297d28Sopenharmony_ci
70e9297d28Sopenharmony_ci    return image->nativeWindow;
71e9297d28Sopenharmony_ci}
72e9297d28Sopenharmony_ci
73e9297d28Sopenharmony_ciint32_t OH_NativeImage_AttachContext(OH_NativeImage* image, uint32_t textureId)
74e9297d28Sopenharmony_ci{
75e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
76e9297d28Sopenharmony_ci        BLOGE("parameter error");
77e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
78e9297d28Sopenharmony_ci    }
79e9297d28Sopenharmony_ci    return image->consumer->AttachContext(textureId);
80e9297d28Sopenharmony_ci}
81e9297d28Sopenharmony_ci
82e9297d28Sopenharmony_ciint32_t OH_NativeImage_DetachContext(OH_NativeImage* image)
83e9297d28Sopenharmony_ci{
84e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
85e9297d28Sopenharmony_ci        BLOGE("parameter error");
86e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
87e9297d28Sopenharmony_ci    }
88e9297d28Sopenharmony_ci    return image->consumer->DetachContext();
89e9297d28Sopenharmony_ci}
90e9297d28Sopenharmony_ci
91e9297d28Sopenharmony_ciint32_t OH_NativeImage_UpdateSurfaceImage(OH_NativeImage* image)
92e9297d28Sopenharmony_ci{
93e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
94e9297d28Sopenharmony_ci        BLOGE("parameter error");
95e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
96e9297d28Sopenharmony_ci    }
97e9297d28Sopenharmony_ci    return image->consumer->UpdateSurfaceImage();
98e9297d28Sopenharmony_ci}
99e9297d28Sopenharmony_ci
100e9297d28Sopenharmony_ciint64_t OH_NativeImage_GetTimestamp(OH_NativeImage* image)
101e9297d28Sopenharmony_ci{
102e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
103e9297d28Sopenharmony_ci        BLOGE("parameter error");
104e9297d28Sopenharmony_ci        return -1;
105e9297d28Sopenharmony_ci    }
106e9297d28Sopenharmony_ci    return image->consumer->GetTimeStamp();
107e9297d28Sopenharmony_ci}
108e9297d28Sopenharmony_ci
109e9297d28Sopenharmony_ciint32_t OH_NativeImage_GetTransformMatrix(OH_NativeImage* image, float matrix[16])
110e9297d28Sopenharmony_ci{
111e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr || matrix == nullptr) {
112e9297d28Sopenharmony_ci        BLOGE("parameter error");
113e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
114e9297d28Sopenharmony_ci    }
115e9297d28Sopenharmony_ci    return image->consumer->GetTransformMatrix(matrix);
116e9297d28Sopenharmony_ci}
117e9297d28Sopenharmony_ci
118e9297d28Sopenharmony_ciint32_t OH_NativeImage_GetTransformMatrixV2(OH_NativeImage* image, float matrix[16])
119e9297d28Sopenharmony_ci{
120e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr || matrix == nullptr) {
121e9297d28Sopenharmony_ci        BLOGE("parameter error");
122e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
123e9297d28Sopenharmony_ci    }
124e9297d28Sopenharmony_ci    return image->consumer->GetTransformMatrixV2(matrix);
125e9297d28Sopenharmony_ci}
126e9297d28Sopenharmony_ci
127e9297d28Sopenharmony_ciint32_t OH_NativeImage_GetSurfaceId(OH_NativeImage* image, uint64_t* surfaceId)
128e9297d28Sopenharmony_ci{
129e9297d28Sopenharmony_ci    if (image == nullptr || surfaceId == nullptr || image->consumer == nullptr) {
130e9297d28Sopenharmony_ci        BLOGE("parameter error");
131e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
132e9297d28Sopenharmony_ci    }
133e9297d28Sopenharmony_ci    *surfaceId = image->consumer->GetUniqueId();
134e9297d28Sopenharmony_ci
135e9297d28Sopenharmony_ci    if (image->pSurface == nullptr) {
136e9297d28Sopenharmony_ci        image->pSurface = Surface::CreateSurfaceAsProducer(image->producer);
137e9297d28Sopenharmony_ci    }
138e9297d28Sopenharmony_ci    BLOGE_CHECK_AND_RETURN_RET(image->pSurface != nullptr, SURFACE_ERROR_UNKOWN, "pSurface is null");
139e9297d28Sopenharmony_ci    return SURFACE_ERROR_OK;
140e9297d28Sopenharmony_ci}
141e9297d28Sopenharmony_ci
142e9297d28Sopenharmony_ciint32_t OH_NativeImage_SetOnFrameAvailableListener(OH_NativeImage* image, OH_OnFrameAvailableListener listener)
143e9297d28Sopenharmony_ci{
144e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
145e9297d28Sopenharmony_ci        BLOGE("parameter error");
146e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
147e9297d28Sopenharmony_ci    }
148e9297d28Sopenharmony_ci    return image->consumer->SetOnBufferAvailableListener(listener.context, listener.onFrameAvailable);
149e9297d28Sopenharmony_ci}
150e9297d28Sopenharmony_ci
151e9297d28Sopenharmony_ciint32_t OH_NativeImage_UnsetOnFrameAvailableListener(OH_NativeImage* image)
152e9297d28Sopenharmony_ci{
153e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
154e9297d28Sopenharmony_ci        BLOGE("parameter error");
155e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
156e9297d28Sopenharmony_ci    }
157e9297d28Sopenharmony_ci    return image->consumer->UnsetOnBufferAvailableListener();
158e9297d28Sopenharmony_ci}
159e9297d28Sopenharmony_ci
160e9297d28Sopenharmony_civoid OH_NativeImage_Destroy(OH_NativeImage** image)
161e9297d28Sopenharmony_ci{
162e9297d28Sopenharmony_ci    if (image == nullptr || *image == nullptr) {
163e9297d28Sopenharmony_ci        BLOGE("parameter error");
164e9297d28Sopenharmony_ci        return;
165e9297d28Sopenharmony_ci    }
166e9297d28Sopenharmony_ci    if ((*image)->consumer != nullptr) {
167e9297d28Sopenharmony_ci        (void)(*image)->consumer->UnsetOnBufferAvailableListener();
168e9297d28Sopenharmony_ci    }
169e9297d28Sopenharmony_ci
170e9297d28Sopenharmony_ci    if ((*image)->nativeWindow != nullptr) {
171e9297d28Sopenharmony_ci        DestoryNativeWindow((*image)->nativeWindow);
172e9297d28Sopenharmony_ci        (*image)->nativeWindow = nullptr;
173e9297d28Sopenharmony_ci    }
174e9297d28Sopenharmony_ci
175e9297d28Sopenharmony_ci    delete *image;
176e9297d28Sopenharmony_ci    *image = nullptr;
177e9297d28Sopenharmony_ci}
178e9297d28Sopenharmony_ci
179e9297d28Sopenharmony_ciint32_t OH_NativeImage_AcquireNativeWindowBuffer(OH_NativeImage* image,
180e9297d28Sopenharmony_ci    OHNativeWindowBuffer** nativeWindowBuffer, int32_t* fenceFd)
181e9297d28Sopenharmony_ci{
182e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
183e9297d28Sopenharmony_ci        BLOGE("parameter error");
184e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
185e9297d28Sopenharmony_ci    }
186e9297d28Sopenharmony_ci    return image->consumer->AcquireNativeWindowBuffer(nativeWindowBuffer, fenceFd);
187e9297d28Sopenharmony_ci}
188e9297d28Sopenharmony_ci
189e9297d28Sopenharmony_ciint32_t OH_NativeImage_ReleaseNativeWindowBuffer(OH_NativeImage* image,
190e9297d28Sopenharmony_ci    OHNativeWindowBuffer* nativeWindowBuffer, int32_t fenceFd)
191e9297d28Sopenharmony_ci{
192e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
193e9297d28Sopenharmony_ci        BLOGE("parameter error");
194e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
195e9297d28Sopenharmony_ci    }
196e9297d28Sopenharmony_ci    return image->consumer->ReleaseNativeWindowBuffer(nativeWindowBuffer, fenceFd);
197e9297d28Sopenharmony_ci}
198e9297d28Sopenharmony_ci
199e9297d28Sopenharmony_ci
200e9297d28Sopenharmony_ciint32_t OH_ConsumerSurface_SetDefaultUsage(OH_NativeImage* image, uint64_t usage)
201e9297d28Sopenharmony_ci{
202e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr) {
203e9297d28Sopenharmony_ci        BLOGE("parameter error");
204e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
205e9297d28Sopenharmony_ci    }
206e9297d28Sopenharmony_ci    return image->consumer->SetDefaultUsage(usage);
207e9297d28Sopenharmony_ci}
208e9297d28Sopenharmony_ci
209e9297d28Sopenharmony_ciint32_t OH_ConsumerSurface_SetDefaultSize(OH_NativeImage* image, int32_t width, int32_t height)
210e9297d28Sopenharmony_ci{
211e9297d28Sopenharmony_ci    if (image == nullptr || image->consumer == nullptr || width <= 0 || height <= 0) {
212e9297d28Sopenharmony_ci        BLOGE("parameter error");
213e9297d28Sopenharmony_ci        return SURFACE_ERROR_INVALID_PARAM;
214e9297d28Sopenharmony_ci    }
215e9297d28Sopenharmony_ci    return image->consumer->SetDefaultSize(width, height);
216e9297d28Sopenharmony_ci}