* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_SURFACE_IMAGE_H
#define FRAMEWORKS_SURFACE_IMAGE_H
#include <atomic>
#include <mutex>
#include <array>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES3/gl32.h>
#include "buffer_log.h"
#include "consumer_surface.h"
#include "native_window.h"
namespace OHOS {
struct ImageCacheSeq {
ImageCacheSeq() : eglImage_(EGL_NO_IMAGE_KHR), eglSync_(EGL_NO_SYNC_KHR) {}
EGLImageKHR eglImage_;
EGLSyncKHR eglSync_;
};
static constexpr uint32_t TRANSFORM_MATRIX_ELE_COUNT = 16;
typedef void (*OnBufferAvailableListener)(void *context);
class SurfaceImage : public ConsumerSurface {
public:
SurfaceImage(uint32_t textureId, uint32_t textureTarget = GL_TEXTURE_EXTERNAL_OES);
SurfaceImage();
virtual ~SurfaceImage();
void InitSurfaceImage();
std::string GetSurfaceImageName() const
{
return surfaceImageName_;
}
SurfaceError UpdateSurfaceImage();
int64_t GetTimeStamp();
void OnUpdateBufferAvailableState(bool updated)
{
updateSurfaceImage_ = updated;
}
bool GetBufferAvailableState()
{
return updateSurfaceImage_;
}
SurfaceError AttachContext(uint32_t textureId);
SurfaceError DetachContext();
SurfaceError GetTransformMatrix(float matrix[16]);
SurfaceError GetTransformMatrixV2(float matrix[16]);
SurfaceError GetBufferMatrix(float matrix[16]);
SurfaceError SetOnBufferAvailableListener(void *context, OnBufferAvailableListener listener);
SurfaceError UnsetOnBufferAvailableListener();
OnBufferAvailableListener listener_ = nullptr;
void *context_ = nullptr;
SurfaceError AcquireNativeWindowBuffer(OHNativeWindowBuffer** nativeWindowBuffer, int32_t* fenceFd,
bool isLatest = false);
SurfaceError ReleaseNativeWindowBuffer(OHNativeWindowBuffer* nativeWindowBuffer, int32_t fenceFd);
SurfaceError SetDefaultUsage(uint64_t usage);
SurfaceError SetDefaultSize(int32_t width, int32_t height);
SurfaceError SetDropBufferSwitch(bool isOpen);
SurfaceError OnBufferAvailable();
SurfaceError ReleaseTextImage();
SurfaceError GetColorSpace(OH_NativeBuffer_ColorSpace* colorSpace);
SurfaceError isReleased(bool* isReleased);
private:
void UpdateBasicInfo(const sptr<SurfaceBuffer>& buffer, int64_t timestamp);
Rect GetBufferCropRegion(const sptr<OHOS::SurfaceBuffer>& buffer);
SurfaceError ValidateEglState();
EGLImageKHR CreateEGLImage(EGLDisplay disp, const sptr<SurfaceBuffer>& buffer);
SurfaceError UpdateEGLImageAndTexture(const sptr<SurfaceBuffer>& buffer);
void UpdateSurfaceInfo(sptr<SurfaceBuffer> buffer, const sptr<SyncFence> &acquireFence,
int64_t timestamp, const Rect& damage);
void CheckImageCacheNeedClean(uint32_t seqNum);
void DestroyEGLImage(EGLImageKHR &eglImage);
void DestroyEGLSync(EGLSyncKHR &eglSync);
void NewBufferDestroyEGLImage(bool isNewBuffer, uint32_t seqNum);
void DestroyEGLImageBySeq(uint32_t seqNum);
uint32_t textureId_ = 0;
uint32_t textureTarget_ = GL_TEXTURE_EXTERNAL_OES;
std::string surfaceImageName_;
std::mutex opMutex_;
std::atomic<bool> updateSurfaceImage_;
EGLDisplay eglDisplay_ = EGL_NO_DISPLAY;
EGLContext eglContext_ = EGL_NO_CONTEXT;
std::map<uint32_t, ImageCacheSeq> imageCacheSeqs_;
uint32_t currentSurfaceImage_ = UINT_MAX;
sptr<SurfaceBuffer> currentSurfaceBuffer_;
int64_t currentTimeStamp_;
OH_NativeBuffer_ColorSpace colorSpace_ = OH_COLORSPACE_NONE;
bool isReleased_ = false;
float currentTransformMatrix_[TRANSFORM_MATRIX_ELE_COUNT] = {0.0};
float currentTransformMatrixV2_[TRANSFORM_MATRIX_ELE_COUNT] = {0.0};
float currentBufferMatrix_[TRANSFORM_MATRIX_ELE_COUNT] = {0.0};
uint64_t uniqueId_ = 0;
bool dropFrameMode_ = false;
* @brief Represents the properties of a graphics buffer frame
*
* This structure encapsulates essential information about a graphics buffer frame,
* including its effective region, dimensions, and transformation settings. It is used
* to track and compare buffer states for efficient graphics rendering and processing.
*/
struct BufferProperties {
* @brief Defines the valid/effective region within the buffer
* Represents the actual usable area of the buffer that contains valid content,
* which may be smaller than the full buffer dimensions
*/
Rect crop = {0, 0, 0, 0};
* @brief Rotation/transformation type applied to the buffer
* Specifies how the buffer content should be transformed during rendering
*/
GraphicTransformType transformType = GraphicTransformType::GRAPHIC_ROTATE_NONE;
* @brief Width of the buffer in pixels
* Represents the horizontal dimension of the graphics buffer
*/
uint32_t bufferWidth = 0;
* @brief Height of the buffer in pixels
* Represents the vertical dimension of the graphics buffer
*/
uint32_t bufferHeight = 0;
* @brief Equality comparison operator
* @param other The BufferProperties object to compare with
* @return true if all properties match, false otherwise
*/
bool operator==(const BufferProperties& other) const
{
return crop == other.crop &&
transformType == other.transformType &&
bufferWidth == other.bufferWidth &&
bufferHeight == other.bufferHeight;
}
* @brief Inequality comparison operator
* @param other The BufferProperties object to compare with
* @return true if any property differs, false if all match
*/
bool operator!=(const BufferProperties& other) const
{
return !(*this == other);
}
};
BufferProperties bufferProperties_;
BufferProperties preBufferProperties_;
};
class SurfaceImageListener : public IBufferConsumerListener {
public:
explicit SurfaceImageListener(const sptr<SurfaceImage> & surfaceImage) : surfaceImage_(surfaceImage)
{
BLOGD("SurfaceImageListener");
};
virtual ~SurfaceImageListener();
virtual void OnBufferAvailable() override;
private:
wptr<SurfaceImage> surfaceImage_;
};
}
#endif