1 /*
2  * Copyright (c) 2021 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 #ifndef FRAMEWORKS_SURFACE_IMAGE_H
17 #define FRAMEWORKS_SURFACE_IMAGE_H
18 
19 #include <atomic>
20 #include <mutex>
21 #include <array>
22 
23 #include <EGL/egl.h>
24 #include <EGL/eglext.h>
25 #include <GLES/gl.h>
26 #include <GLES/glext.h>
27 #include <GLES3/gl32.h>
28 #include "buffer_log.h"
29 #include "consumer_surface.h"
30 #include "native_window.h"
31 
32 namespace OHOS {
33 struct ImageCacheSeq {
ImageCacheSeqImageCacheSeq34     ImageCacheSeq() : eglImage_(EGL_NO_IMAGE_KHR), eglSync_(EGL_NO_SYNC_KHR) {}
35     EGLImageKHR eglImage_;
36     EGLSyncKHR eglSync_;
37 };
38 
39 static constexpr int64_t TRANSFORM_MATRIX_ELE_COUNT = 16;
40 typedef void (*OnBufferAvailableListener)(void *context);
41 
42 class SurfaceImage : public ConsumerSurface {
43 public:
44     SurfaceImage(uint32_t textureId, uint32_t textureTarget = GL_TEXTURE_EXTERNAL_OES);
45     SurfaceImage();
46     virtual ~SurfaceImage();
47 
48     void InitSurfaceImage();
49 
GetSurfaceImageName()50     std::string GetSurfaceImageName() const
51     {
52         return surfaceImageName_;
53     }
54 
55     SurfaceError UpdateSurfaceImage();
56     int64_t GetTimeStamp();
57 
58     // update buffer available state, updateSurfaceImage_ and a private mutex
OnUpdateBufferAvailableState(bool updated)59     void OnUpdateBufferAvailableState(bool updated)
60     {
61         updateSurfaceImage_ = updated;
62     }
63 
GetBufferAvailableState()64     bool GetBufferAvailableState()
65     {
66         return updateSurfaceImage_;
67     }
68 
69     SurfaceError AttachContext(uint32_t textureId);
70     SurfaceError DetachContext();
71 
72     SurfaceError GetTransformMatrix(float matrix[16]);
73     SurfaceError GetTransformMatrixV2(float matrix[16]);
74     SurfaceError SetOnBufferAvailableListener(void *context, OnBufferAvailableListener listener);
75     SurfaceError UnsetOnBufferAvailableListener();
76     OnBufferAvailableListener listener_ = nullptr;
77     void *context_ = nullptr;
78 
79     SurfaceError AcquireNativeWindowBuffer(OHNativeWindowBuffer** nativeWindowBuffer, int32_t* fenceFd);
80     SurfaceError ReleaseNativeWindowBuffer(OHNativeWindowBuffer* nativeWindowBuffer, int32_t fenceFd);
81 
82     SurfaceError SetDefaultUsage(uint64_t usage);
83     SurfaceError SetDefaultSize(int32_t width, int32_t height);
84 private:
85     SurfaceError ValidateEglState();
86     EGLImageKHR CreateEGLImage(EGLDisplay disp, const sptr<SurfaceBuffer>& buffer);
87     SurfaceError UpdateEGLImageAndTexture(const sptr<SurfaceBuffer>& buffer);
88     void UpdateSurfaceInfo(uint32_t seqNum, sptr<SurfaceBuffer> buffer, const sptr<SyncFence> &acquireFence,
89                            int64_t timestamp, Rect damage);
90     void CheckImageCacheNeedClean(uint32_t seqNum);
91     void DestroyEGLImage(EGLImageKHR &eglImage);
92     void DestroyEGLSync(EGLSyncKHR &eglSync);
93     void NewBufferDestroyEGLImage(bool isNewBuffer, uint32_t seqNum);
94     void DestroyEGLImageBySeq(uint32_t seqNum);
95 
96     uint32_t textureId_ = 0;
97     uint32_t textureTarget_ = GL_TEXTURE_EXTERNAL_OES;
98     std::string surfaceImageName_;
99 
100     std::mutex opMutex_;
101     std::atomic<bool> updateSurfaceImage_;
102 
103     EGLDisplay eglDisplay_ = EGL_NO_DISPLAY;
104     EGLContext eglContext_ = EGL_NO_CONTEXT;
105     std::map<uint32_t, ImageCacheSeq> imageCacheSeqs_;
106     uint32_t currentSurfaceImage_ = UINT_MAX;
107     sptr<SurfaceBuffer> currentSurfaceBuffer_;
108     int64_t currentTimeStamp_;
109     Rect currentCrop_ = {};
110     GraphicTransformType currentTransformType_ = GraphicTransformType::GRAPHIC_ROTATE_NONE;
111     float currentTransformMatrix_[TRANSFORM_MATRIX_ELE_COUNT] = {0.0};
112     float currentTransformMatrixV2_[TRANSFORM_MATRIX_ELE_COUNT] = {0.0};
113     uint64_t uniqueId_ = 0;
114 };
115 
116 class SurfaceImageListener : public IBufferConsumerListener {
117 public:
SurfaceImageListener(const sptr<SurfaceImage> & surfaceImage)118     explicit SurfaceImageListener(const sptr<SurfaceImage> & surfaceImage) : surfaceImage_(surfaceImage)
119     {
120         BLOGI("SurfaceImageListener");
121     };
122     virtual ~SurfaceImageListener();
123 
124     virtual void OnBufferAvailable() override;
125 
126 private:
127     wptr<SurfaceImage> surfaceImage_;
128 };
129 } // namespace OHOS
130 #endif // FRAMEWORKS_SURFACE_IMAGE_H
131