#include "ui/gl/ohos/native_buffer_utils.h"
#include "ui/gl/gl_context.h"
#include "ui/gl/gl_fence_android_native_fence_sync.h"
#include "ui/gl/gl_gl_api_implementation.h"
#include "ui/gl/gl_surface_egl.h"
#include "ui/gl/gl_utils.h"
#include "ui/gl/gl_version_info.h"
#include "ui/gl/scoped_binders.h"
#include "ui/gl/scoped_egl_image.h"
#include "base/trace_event/trace_event.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <sys/poll.h>
namespace gl {
namespace ohos {
gl::ScopedEGLImage CreateEGLImage(EGLClientBuffer egl_client_buffer) {
EGLint attrs[] = {
EGL_IMAGE_PRESERVED,
EGL_TRUE,
EGL_NONE,
};
return gl::MakeScopedEGLImage(EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS,
egl_client_buffer, attrs);
}
gl::ScopedEGLImage CreateEGLImageForVideo(EGLClientBuffer egl_client_buffer) {
EGLint attrs[] = {
EGL_IMAGE_PRESERVED,
EGL_FALSE,
EGL_NONE,
};
return gl::MakeScopedEGLImage(EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_OHOS,
egl_client_buffer, attrs);
}
int GetEGLClientBufferFromNativeBuffer(void* ohos_native_buffer,
void** egl_client_buffer) {
return OHOS::NWeb::OhosAdapterHelper::GetInstance()
.GetOhosNativeBufferAdapter()
.GetEGLBuffer(ohos_native_buffer, egl_client_buffer);
}
void FreeEGLClientBuffer(EGLClientBuffer egl_client_buffer) {
OHOS::NWeb::OhosAdapterHelper::GetInstance()
.GetOhosNativeBufferAdapter()
.FreeEGLBuffer(egl_client_buffer);
}
bool InsertEglFenceAndWait(base::ScopedFD acquire_fence_fd) {
int fence_fd = acquire_fence_fd.release();
if (fence_fd == -1) {
return true;
}
EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fence_fd, EGL_NONE};
std::unique_ptr<gl::GLFenceEGL> egl_fence(
gl::GLFenceEGL::Create(EGL_SYNC_NATIVE_FENCE_ANDROID, attribs));
if (egl_fence == nullptr) {
base::ScopedFD temp_fd(fence_fd);
LOG(ERROR) << " Failed to created egl fence object ";
return false;
}
egl_fence->ServerWait();
return true;
}
bool SyncFenceWait(base::ScopedFD acquire_fence_fd) {
int fence_fd = acquire_fence_fd.get();
TRACE_EVENT1("base", "SyncFenceWait", "sync_fd", fence_fd);
if (fence_fd == -1) {
return true;
}
struct pollfd poll_fds = {0};
poll_fds.fd = fence_fd;
poll_fds.events = POLLIN;
int ret = -1;
do {
ret = poll(&poll_fds, 1, -1);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
if (ret == 0) {
ret = -1;
errno = ETIME;
} else if (ret > 0) {
ret = 0;
if (poll_fds.revents & (POLLERR | POLLNVAL)) {
ret = -1;
errno = EINVAL;
}
}
if (ret < 0) {
LOG(ERROR) << "Failed to do SyncFenceWait errno " << errno;
return false;
}
return true;
}
}
}