mirror of
https://gitee.com/openharmony/graphic_graphic_2d
synced 2024-11-28 01:34:16 +00:00
commit
d3e787aa16
@ -17,6 +17,7 @@
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base/test:render_service_client",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_client/test:render_service_client_surface_node_demo",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service:librender_service",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service:render_service"
|
||||
|
@ -1,288 +1,286 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "render_context.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC;
|
||||
constexpr const char *EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland";
|
||||
constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland";
|
||||
constexpr int32_t EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
|
||||
constexpr char CHARACTER_WHITESPACE = ' ';
|
||||
constexpr const char *CHARACTER_STRING_WHITESPACE = " ";
|
||||
constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT";
|
||||
|
||||
static bool CheckEglExtension(const char *extensions, const char *extension)
|
||||
{
|
||||
size_t extlen = strlen(extension);
|
||||
const char *end = extensions + strlen(extensions);
|
||||
|
||||
while (extensions < end) {
|
||||
size_t n = 0;
|
||||
/* Skip whitespaces, if any */
|
||||
if (*extensions == CHARACTER_WHITESPACE) {
|
||||
extensions++;
|
||||
continue;
|
||||
}
|
||||
|
||||
n = strcspn(extensions, CHARACTER_STRING_WHITESPACE);
|
||||
|
||||
/* Compare strings */
|
||||
if (n == extlen && strncmp(extension, extensions, n) == 0) {
|
||||
return true; /* Found */
|
||||
}
|
||||
extensions += n;
|
||||
}
|
||||
/* Not found */
|
||||
return false;
|
||||
}
|
||||
|
||||
static EGLDisplay GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list)
|
||||
{
|
||||
static GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL;
|
||||
|
||||
if (!eglGetPlatformDisplayExt) {
|
||||
const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
if (extensions &&
|
||||
(CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) ||
|
||||
CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) {
|
||||
eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT);
|
||||
}
|
||||
}
|
||||
|
||||
if (eglGetPlatformDisplayExt) {
|
||||
return eglGetPlatformDisplayExt(platform, native_display, attrib_list);
|
||||
}
|
||||
|
||||
return eglGetDisplay((EGLNativeDisplayType) native_display);
|
||||
}
|
||||
|
||||
RenderContext::RenderContext()
|
||||
: grContext_(nullptr), skSurface_(nullptr), skCanvas_(nullptr), nativeWindow_(nullptr),
|
||||
eglDisplay_(nullptr), eglContext_(nullptr), eglSurface_(nullptr), config_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
RenderContext::~RenderContext()
|
||||
{
|
||||
eglDestroyContext(eglDisplay_, eglContext_);
|
||||
eglTerminate(eglDisplay_);
|
||||
eglReleaseThread();
|
||||
|
||||
grContext_ = nullptr;
|
||||
skSurface_ = nullptr;
|
||||
skCanvas_ = nullptr;
|
||||
}
|
||||
|
||||
void RenderContext::InitializeEglContext()
|
||||
{
|
||||
eglDisplay_ = GetPlatformEglDisplay(EGL_PLATFORM_OHOS, EGL_DEFAULT_DISPLAY, NULL);
|
||||
if (eglDisplay_ == EGL_NO_DISPLAY) {
|
||||
LOGW("Failed to create EGLDisplay gl errno : %{public}x", eglGetError());
|
||||
return;
|
||||
}
|
||||
|
||||
LOGW("EGLDisplay is : %{public}p, rendercontext is %{public}p", eglDisplay_, this);
|
||||
|
||||
EGLint major, minor;
|
||||
if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
|
||||
LOGW("Failed to initialize EGLDisplay");
|
||||
return;
|
||||
}
|
||||
|
||||
if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
|
||||
LOGW("Failed to bind OpenGL ES API");
|
||||
return;
|
||||
}
|
||||
|
||||
EGLint ret, count;
|
||||
EGLint config_attribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
ret = eglChooseConfig(eglDisplay_, config_attribs, &config_, 1, &count);
|
||||
if (!(ret && count >= 1)) {
|
||||
LOGW("Failed to eglChooseConfig");
|
||||
return;
|
||||
}
|
||||
|
||||
static const EGLint context_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
if (eglContext_ == EGL_NO_CONTEXT) {
|
||||
eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, context_attribs);
|
||||
if (eglContext_ == EGL_NO_CONTEXT) {
|
||||
LOGW("CreateEGLSurface failed to eglCreateContext %{public}x", eglGetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOGW("InitializeEglContext finished");
|
||||
}
|
||||
|
||||
void RenderContext::MakeCurrent(EGLSurface surface) const
|
||||
{
|
||||
if ((eglDisplay_ != nullptr) && (eglContext_ != EGL_NO_CONTEXT) && (surface != nullptr)) {
|
||||
LOGW("MakeCurrent successfully, context is %{public}p", this);
|
||||
eglMakeCurrent(eglDisplay_, surface, surface, eglContext_);
|
||||
} else {
|
||||
LOGE("Can not makeCurrent!!!");
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContext::SwapBuffers(EGLSurface surface) const
|
||||
{
|
||||
if ((eglDisplay_ != nullptr) && (surface != nullptr)) {
|
||||
LOGW("SwapBuffers successfully, context is %{public}p", this);
|
||||
eglSwapBuffers(eglDisplay_, surface);
|
||||
} else {
|
||||
LOGW("Can not SwapBuffers!!!");
|
||||
}
|
||||
}
|
||||
|
||||
EGLSurface RenderContext::CreateEGLSurface(EGLNativeWindowType eglNativeWindow)
|
||||
{
|
||||
nativeWindow_ = eglNativeWindow;
|
||||
|
||||
eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
EGLint winAttribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE};
|
||||
EGLSurface surface = eglCreateWindowSurface(eglDisplay_, config_, nativeWindow_, winAttribs);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
LOGW("CreateEGLSurface failed to create eglsurface %{public}x", eglGetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOGW("CreateEGLSurface: eglDisplay_ is %{public}p, eglSurface_ is %{public}p", eglDisplay_, surface);
|
||||
|
||||
eglSurface_ = surface;
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void SetUpGrContext(sk_sp<GrContext>& grContext)
|
||||
{
|
||||
if (grContext != nullptr) {
|
||||
LOGW("grContext has already created!!");
|
||||
return;
|
||||
}
|
||||
|
||||
sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
|
||||
if (glInterface == nullptr) {
|
||||
LOGW("SetUpGrContext failed to make native interface");
|
||||
return;
|
||||
}
|
||||
|
||||
GrContextOptions options;
|
||||
options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
|
||||
options.fPreferExternalImagesOverES3 = true;
|
||||
options.fDisableDistanceFieldPaths = true;
|
||||
|
||||
grContext = GrContext::MakeGL(std::move(glInterface), options);
|
||||
if (grContext == nullptr) {
|
||||
LOGE("SetUpGrContext grContext is null");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGI("SetUpGrContext successfully!");
|
||||
}
|
||||
|
||||
void RenderContext::CreateCanvas(int width, int height)
|
||||
{
|
||||
if (skCanvas_ != nullptr) {
|
||||
LOGW("canvas has been created!!");
|
||||
return;
|
||||
}
|
||||
|
||||
SetUpGrContext(grContext_);
|
||||
|
||||
GrGLFramebufferInfo framebufferInfo;
|
||||
framebufferInfo.fFBOID = 0;
|
||||
framebufferInfo.fFormat = GL_RGBA8;
|
||||
|
||||
SkColorType colorType = kRGBA_8888_SkColorType;
|
||||
|
||||
GrBackendRenderTarget backendRenderTarget(width, height, 0, 8, framebufferInfo);
|
||||
SkSurfaceProps surfaceProps = SkSurfaceProps::kLegacyFontHost_InitType;
|
||||
|
||||
skSurface_ = SkSurface::MakeFromBackendRenderTarget(grContext_.get(), backendRenderTarget,
|
||||
kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &surfaceProps);
|
||||
if (skSurface_ == nullptr) {
|
||||
LOGW("skSurface is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
skCanvas_ = skSurface_->getCanvas();
|
||||
if (skCanvas_ == nullptr) {
|
||||
LOGE("CreateCanvas failed, skCanvas_ is null");
|
||||
return;
|
||||
}
|
||||
LOGE("CreateCanvas successfully!!!");
|
||||
}
|
||||
|
||||
SkCanvas* RenderContext::GetCanvas() const
|
||||
{
|
||||
return skCanvas_;
|
||||
}
|
||||
|
||||
void RenderContext::RenderFrame()
|
||||
{
|
||||
// flush commands
|
||||
if (skCanvas_ != nullptr) {
|
||||
LOGW("RenderFrame: %{public}p", this);
|
||||
skCanvas_->flush();
|
||||
} else {
|
||||
LOGW("RenderFrame failed!!!");
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContext::DamageFrame(int32_t left, int32_t top, int32_t width, int32_t height)
|
||||
{
|
||||
#if EGL_EGLEXT_PROTOTYPES
|
||||
RenderContext* rc = RenderContextFactory::GetInstance().CreateEngine();
|
||||
EGLDisplay eglDisplay = rc->GetEGLDisplay();
|
||||
EGLSurface eglSurface = rc->GetEGLSurface();
|
||||
|
||||
if ((eglDisplay == nullptr) || (eglSurface == nullptr)) {
|
||||
LOGE("eglDisplay or eglSurface is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
EGLint rect[4];
|
||||
rect[0] = left;
|
||||
rect[1] = top;
|
||||
rect[2] = width;
|
||||
rect[3] = height;
|
||||
|
||||
if (!eglSetDamageRegionKHR(eglDisplay, eglSurface, rect, 0)) {
|
||||
LOGE("eglSetDamageRegionKHR is failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "render_context.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC;
|
||||
constexpr const char *EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland";
|
||||
constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland";
|
||||
constexpr int32_t EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
|
||||
constexpr char CHARACTER_WHITESPACE = ' ';
|
||||
constexpr const char *CHARACTER_STRING_WHITESPACE = " ";
|
||||
constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT";
|
||||
|
||||
static bool CheckEglExtension(const char *extensions, const char *extension)
|
||||
{
|
||||
size_t extlen = strlen(extension);
|
||||
const char *end = extensions + strlen(extensions);
|
||||
|
||||
while (extensions < end) {
|
||||
size_t n = 0;
|
||||
/* Skip whitespaces, if any */
|
||||
if (*extensions == CHARACTER_WHITESPACE) {
|
||||
extensions++;
|
||||
continue;
|
||||
}
|
||||
|
||||
n = strcspn(extensions, CHARACTER_STRING_WHITESPACE);
|
||||
|
||||
/* Compare strings */
|
||||
if (n == extlen && strncmp(extension, extensions, n) == 0) {
|
||||
return true; /* Found */
|
||||
}
|
||||
extensions += n;
|
||||
}
|
||||
/* Not found */
|
||||
return false;
|
||||
}
|
||||
|
||||
static EGLDisplay GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list)
|
||||
{
|
||||
static GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL;
|
||||
|
||||
if (!eglGetPlatformDisplayExt) {
|
||||
const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
if (extensions &&
|
||||
(CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) ||
|
||||
CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) {
|
||||
eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT);
|
||||
}
|
||||
}
|
||||
|
||||
if (eglGetPlatformDisplayExt) {
|
||||
return eglGetPlatformDisplayExt(platform, native_display, attrib_list);
|
||||
}
|
||||
|
||||
return eglGetDisplay((EGLNativeDisplayType) native_display);
|
||||
}
|
||||
|
||||
RenderContext::RenderContext()
|
||||
: grContext_(nullptr), skSurface_(nullptr), nativeWindow_(nullptr),
|
||||
eglDisplay_(EGL_NO_DISPLAY), eglContext_(EGL_NO_CONTEXT), eglSurface_(EGL_NO_SURFACE), config_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
RenderContext::~RenderContext()
|
||||
{
|
||||
if (eglDisplay_ == EGL_NO_DISPLAY) {
|
||||
return;
|
||||
}
|
||||
eglDestroyContext(eglDisplay_, eglContext_);
|
||||
eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglTerminate(eglDisplay_);
|
||||
eglReleaseThread();
|
||||
|
||||
eglDisplay_ = EGL_NO_DISPLAY;
|
||||
eglContext_ = EGL_NO_CONTEXT;
|
||||
eglSurface_ = EGL_NO_SURFACE;
|
||||
grContext_ = nullptr;
|
||||
skSurface_ = nullptr;
|
||||
}
|
||||
|
||||
void RenderContext::InitializeEglContext()
|
||||
{
|
||||
if (IsEglContextReady()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGI("Creating EGLContext!!!");
|
||||
eglDisplay_ = GetPlatformEglDisplay(EGL_PLATFORM_OHOS, EGL_DEFAULT_DISPLAY, NULL);
|
||||
if (eglDisplay_ == EGL_NO_DISPLAY) {
|
||||
LOGW("Failed to create EGLDisplay gl errno : %{public}x", eglGetError());
|
||||
return;
|
||||
}
|
||||
|
||||
EGLint major, minor;
|
||||
if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
|
||||
LOGE("Failed to initialize EGLDisplay");
|
||||
return;
|
||||
}
|
||||
|
||||
if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
|
||||
LOGE("Failed to bind OpenGL ES API");
|
||||
return;
|
||||
}
|
||||
|
||||
EGLint ret, count;
|
||||
EGLint config_attribs[] = {
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 8,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
ret = eglChooseConfig(eglDisplay_, config_attribs, &config_, 1, &count);
|
||||
if (!(ret && count >= 1)) {
|
||||
LOGE("Failed to eglChooseConfig");
|
||||
return;
|
||||
}
|
||||
|
||||
static const EGLint context_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, context_attribs);
|
||||
if (eglContext_ == EGL_NO_CONTEXT) {
|
||||
LOGE("Failed to create egl context %{public}x", eglGetError());
|
||||
return;
|
||||
}
|
||||
|
||||
LOGW("Create EGL context successfully, version %{public}d.%{public}d", major, minor);
|
||||
}
|
||||
|
||||
void RenderContext::MakeCurrent(EGLSurface surface) const
|
||||
{
|
||||
if (!eglMakeCurrent(eglDisplay_, surface, surface, eglContext_)) {
|
||||
LOGE("Failed to make current on surface %{public}p, error is %{public}x", surface, eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContext::SwapBuffers(EGLSurface surface) const
|
||||
{
|
||||
if (!eglSwapBuffers(eglDisplay_, surface)) {
|
||||
LOGE("Failed to SwapBuffers on surface %{public}p, error is %{public}x", surface, eglGetError());
|
||||
} else {
|
||||
LOGW("SwapBuffers successfully, surface is %{public}p", surface);
|
||||
}
|
||||
}
|
||||
|
||||
EGLSurface RenderContext::CreateEGLSurface(EGLNativeWindowType eglNativeWindow)
|
||||
{
|
||||
if (!IsEglContextReady()) {
|
||||
LOGE("EGL context has not initialized");
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
nativeWindow_ = eglNativeWindow;
|
||||
|
||||
eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
EGLint winAttribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE};
|
||||
EGLSurface surface = eglCreateWindowSurface(eglDisplay_, config_, nativeWindow_, winAttribs);
|
||||
if (surface == EGL_NO_SURFACE) {
|
||||
LOGW("Failed to create eglsurface!!! %{public}x", eglGetError());
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
LOGW("CreateEGLSurface: %{public}p", surface);
|
||||
|
||||
eglSurface_ = surface;
|
||||
return surface;
|
||||
}
|
||||
|
||||
bool RenderContext::SetUpGrContext()
|
||||
{
|
||||
if (grContext_ != nullptr) {
|
||||
LOGW("grContext has already created!!");
|
||||
return true;
|
||||
}
|
||||
|
||||
sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
|
||||
if (glInterface.get() == nullptr) {
|
||||
LOGE("SetUpGrContext failed to make native interface");
|
||||
return false;
|
||||
}
|
||||
|
||||
GrContextOptions options;
|
||||
options.fGpuPathRenderers &= ~GpuPathRenderers::kCoverageCounting;
|
||||
options.fPreferExternalImagesOverES3 = true;
|
||||
options.fDisableDistanceFieldPaths = true;
|
||||
|
||||
sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
|
||||
if (grContext == nullptr) {
|
||||
LOGE("SetUpGrContext grContext is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
grContext_ = std::move(grContext);
|
||||
return true;
|
||||
}
|
||||
|
||||
SkCanvas* RenderContext::AcquireCanvas(int width, int height)
|
||||
{
|
||||
if (!SetUpGrContext()) {
|
||||
LOGE("GrContext is not ready!!!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrGLFramebufferInfo framebufferInfo;
|
||||
framebufferInfo.fFBOID = 0;
|
||||
framebufferInfo.fFormat = GL_RGBA8;
|
||||
|
||||
SkColorType colorType = kRGBA_8888_SkColorType;
|
||||
|
||||
GrBackendRenderTarget backendRenderTarget(width, height, 0, 8, framebufferInfo);
|
||||
SkSurfaceProps surfaceProps = SkSurfaceProps::kLegacyFontHost_InitType;
|
||||
|
||||
skSurface_ = SkSurface::MakeFromBackendRenderTarget(GetGrContext(), backendRenderTarget,
|
||||
kBottomLeft_GrSurfaceOrigin, colorType, nullptr, &surfaceProps);
|
||||
if (skSurface_ == nullptr) {
|
||||
LOGW("skSurface is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LOGE("CreateCanvas successfully!!! (%{public}p)", skSurface_->getCanvas());
|
||||
return skSurface_->getCanvas();
|
||||
}
|
||||
|
||||
void RenderContext::RenderFrame()
|
||||
{
|
||||
// flush commands
|
||||
if (skSurface_->getCanvas() != nullptr) {
|
||||
LOGW("RenderFrame: Canvas is %{public}p", skSurface_->getCanvas());
|
||||
skSurface_->getCanvas()->flush();
|
||||
} else {
|
||||
LOGW("canvas is nullptr!!!");
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContext::DamageFrame(int32_t left, int32_t top, int32_t width, int32_t height)
|
||||
{
|
||||
#if EGL_EGLEXT_PROTOTYPES
|
||||
RenderContext* rc = RenderContextFactory::GetInstance().CreateEngine();
|
||||
EGLDisplay eglDisplay = rc->GetEGLDisplay();
|
||||
EGLSurface eglSurface = rc->GetEGLSurface();
|
||||
|
||||
if ((eglDisplay == nullptr) || (eglSurface == nullptr)) {
|
||||
LOGE("eglDisplay or eglSurface is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
EGLint rect[4];
|
||||
rect[0] = left;
|
||||
rect[1] = top;
|
||||
rect[2] = width;
|
||||
rect[3] = height;
|
||||
|
||||
if (!eglSetDamageRegionKHR(eglDisplay, eglSurface, rect, 0)) {
|
||||
LOGE("eglSetDamageRegionKHR is failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +1,117 @@
|
||||
/*
|
||||
* 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 RENDER_CONTEXT_H
|
||||
#define RENDER_CONTEXT_H
|
||||
|
||||
#include "include/gpu/GrContext.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/gpu/gl/GrGLInterface.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "include/core/SkSurface.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
|
||||
#include "GLES3/gl32.h"
|
||||
|
||||
#define GLES_VERSION 2
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class RenderContext {
|
||||
public:
|
||||
RenderContext();
|
||||
virtual ~RenderContext();
|
||||
void CreateCanvas(int width, int height);
|
||||
SkCanvas* GetCanvas() const;
|
||||
void InitializeEglContext();
|
||||
|
||||
GrContext* GetGrContext() const
|
||||
{
|
||||
return grContext_.get();
|
||||
}
|
||||
|
||||
EGLSurface CreateEGLSurface(EGLNativeWindowType eglNativeWindow);
|
||||
void MakeCurrent(EGLSurface surface) const;
|
||||
void SwapBuffers(EGLSurface surface) const;
|
||||
void RenderFrame();
|
||||
void DamageFrame(int32_t left, int32_t top, int32_t width, int32_t height);
|
||||
|
||||
EGLSurface GetEGLSurface() const
|
||||
{
|
||||
return eglSurface_;
|
||||
}
|
||||
|
||||
EGLDisplay GetEGLDisplay() const
|
||||
{
|
||||
return eglDisplay_;
|
||||
}
|
||||
private:
|
||||
sk_sp<GrContext> grContext_;
|
||||
sk_sp<SkSurface> skSurface_;
|
||||
|
||||
SkCanvas* skCanvas_;
|
||||
|
||||
EGLNativeWindowType nativeWindow_;
|
||||
|
||||
EGLDisplay eglDisplay_;
|
||||
EGLContext eglContext_;
|
||||
EGLSurface eglSurface_;
|
||||
EGLConfig config_;
|
||||
};
|
||||
|
||||
class RenderContextFactory {
|
||||
public:
|
||||
~RenderContextFactory()
|
||||
{
|
||||
if (context_ != nullptr) {
|
||||
delete context_;
|
||||
}
|
||||
context_ = nullptr;
|
||||
}
|
||||
|
||||
static RenderContextFactory& GetInstance()
|
||||
{
|
||||
static RenderContextFactory rf;
|
||||
return rf;
|
||||
}
|
||||
|
||||
RenderContext* CreateEngine()
|
||||
{
|
||||
if (context_ == nullptr) {
|
||||
context_ = new RenderContext();
|
||||
}
|
||||
|
||||
return context_;
|
||||
}
|
||||
|
||||
private:
|
||||
RenderContextFactory() : context_(nullptr) {}
|
||||
RenderContextFactory(const RenderContextFactory&) = delete;
|
||||
RenderContextFactory& operator=(const RenderContextFactory&) = delete;
|
||||
|
||||
RenderContext* context_;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* 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 RENDER_CONTEXT_H
|
||||
#define RENDER_CONTEXT_H
|
||||
|
||||
#include "include/gpu/GrContext.h"
|
||||
#include "include/gpu/GrBackendSurface.h"
|
||||
#include "include/gpu/gl/GrGLInterface.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkColorSpace.h"
|
||||
#include "include/core/SkSurface.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
|
||||
#include "EGL/egl.h"
|
||||
#include "EGL/eglext.h"
|
||||
|
||||
#include "GLES3/gl32.h"
|
||||
|
||||
#define GLES_VERSION 2
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class RenderContext {
|
||||
public:
|
||||
RenderContext();
|
||||
virtual ~RenderContext();
|
||||
void CreateCanvas(int width, int height);
|
||||
SkCanvas* AcquireCanvas(int width, int height);
|
||||
|
||||
void InitializeEglContext();
|
||||
|
||||
GrContext* GetGrContext() const
|
||||
{
|
||||
return grContext_.get();
|
||||
}
|
||||
|
||||
bool SetUpGrContext();
|
||||
|
||||
EGLSurface CreateEGLSurface(EGLNativeWindowType eglNativeWindow);
|
||||
void MakeCurrent(EGLSurface surface) const;
|
||||
void SwapBuffers(EGLSurface surface) const;
|
||||
void RenderFrame();
|
||||
void DamageFrame(int32_t left, int32_t top, int32_t width, int32_t height);
|
||||
|
||||
EGLSurface GetEGLSurface() const
|
||||
{
|
||||
return eglSurface_;
|
||||
}
|
||||
|
||||
EGLDisplay GetEGLDisplay() const
|
||||
{
|
||||
return eglDisplay_;
|
||||
}
|
||||
|
||||
bool IsEglContextReady()
|
||||
{
|
||||
return eglContext_ != EGL_NO_DISPLAY;
|
||||
}
|
||||
private:
|
||||
sk_sp<GrContext> grContext_;
|
||||
sk_sp<SkSurface> skSurface_;
|
||||
|
||||
EGLNativeWindowType nativeWindow_;
|
||||
|
||||
EGLDisplay eglDisplay_;
|
||||
EGLContext eglContext_;
|
||||
EGLSurface eglSurface_;
|
||||
EGLConfig config_;
|
||||
};
|
||||
|
||||
class RenderContextFactory {
|
||||
public:
|
||||
~RenderContextFactory()
|
||||
{
|
||||
if (context_ != nullptr) {
|
||||
delete context_;
|
||||
}
|
||||
context_ = nullptr;
|
||||
}
|
||||
|
||||
static RenderContextFactory& GetInstance()
|
||||
{
|
||||
static RenderContextFactory rf;
|
||||
return rf;
|
||||
}
|
||||
|
||||
RenderContext* CreateEngine()
|
||||
{
|
||||
if (context_ == nullptr) {
|
||||
context_ = new RenderContext();
|
||||
}
|
||||
|
||||
return context_;
|
||||
}
|
||||
|
||||
private:
|
||||
RenderContextFactory() : context_(nullptr) {}
|
||||
RenderContextFactory(const RenderContextFactory&) = delete;
|
||||
RenderContextFactory& operator=(const RenderContextFactory&) = delete;
|
||||
|
||||
RenderContext* context_;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -113,7 +113,7 @@ void HdiBackend::Repaint(std::vector<OutputPtr> &outputs)
|
||||
ret = device_->Commit(screenId, fbFence);
|
||||
if (ret != DISPLAY_SUCCESS) {
|
||||
HLOGE("commit failed, ret is %{public}d", ret);
|
||||
return;
|
||||
//return;
|
||||
}
|
||||
|
||||
ReleaseLayerBuffer(screenId, layersMap);
|
||||
|
@ -15,7 +15,6 @@ import("//build/ohos.gni")
|
||||
|
||||
## Build librender_service.so
|
||||
ohos_shared_library("librender_service") {
|
||||
defines = [ "ROSEN_DEBUG" ]
|
||||
sources = [
|
||||
"core/pipeline/rs_compatible_processor.cpp",
|
||||
"core/pipeline/rs_hardware_processor.cpp",
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "pipeline/rs_render_service_util.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
|
||||
#include "common/rs_obj_abs_geometry.h"
|
||||
|
||||
namespace OHOS {
|
||||
|
||||
namespace Rosen {
|
||||
@ -84,15 +86,23 @@ void RSCompatibleProcessor::ProcessSurface(RSSurfaceRenderNode& node)
|
||||
ROSEN_LOGE("RsDebug RSCompatibleProcessor::ProcessSurface consume buffer fail");
|
||||
return;
|
||||
}
|
||||
ROSEN_LOGI("RsDebug RSCompatibleProcessor::ProcessSurface Node id:%llu [%f %f %f %f] buffer [%d %d]",
|
||||
node.GetId(), node.GetRenderProperties().GetBoundsPositionX(), node.GetRenderProperties().GetBoundsPositionY(),
|
||||
node.GetRenderProperties().GetBoundsWidth(), node.GetRenderProperties().GetBoundsHeight(),
|
||||
|
||||
auto geoPtr = std::static_pointer_cast<RSObjAbsGeometry>(node.GetRenderProperties().GetBoundsGeometry());
|
||||
if (geoPtr == nullptr) {
|
||||
ROSEN_LOGE("RsDebug RSCompatibleProcessor::ProcessSurface geoPtr == nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
ROSEN_LOGI("RsDebug RSCompatibleProcessor::ProcessSurface surfaceNode id:%llu [%d %d %d %d] buffer [%d %d]",
|
||||
node.GetId(), geoPtr->GetAbsRect().left_, geoPtr->GetAbsRect().top_,
|
||||
geoPtr->GetAbsRect().width_, geoPtr->GetAbsRect().height_,
|
||||
node.GetBuffer()->GetWidth(), node.GetBuffer()->GetHeight());
|
||||
|
||||
SkMatrix matrix;
|
||||
matrix.reset();
|
||||
RsRenderServiceUtil::DrawBuffer(canvas_.get(), matrix, node.GetBuffer(),
|
||||
node.GetRenderProperties().GetBoundsPositionX(), node.GetRenderProperties().GetBoundsPositionY(),
|
||||
node.GetRenderProperties().GetBoundsWidth(), node.GetRenderProperties().GetBoundsHeight());
|
||||
static_cast<float>(geoPtr->GetAbsRect().left_), static_cast<float>(geoPtr->GetAbsRect().top_),
|
||||
static_cast<float>(geoPtr->GetAbsRect().width_), static_cast<float>(geoPtr->GetAbsRect().height_));
|
||||
}
|
||||
|
||||
void RSCompatibleProcessor::PostProcess()
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
#include "pipeline/rs_hardware_processor.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
#include "pipeline/rs_main_thread.h"
|
||||
#include "pipeline/rs_render_service_util.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
@ -37,9 +39,19 @@ void RSHardwareProcessor::Init(ScreenId id)
|
||||
return;
|
||||
}
|
||||
output_ = screenManager_->GetOutput(id);
|
||||
screenManager_->GetScreenActiveMode(id, curScreenInfo);
|
||||
if (!output_) {
|
||||
ROSEN_LOGE("RSHardwareProcessor::Init output_ is nullptr");
|
||||
return;
|
||||
}
|
||||
screenManager_->GetScreenActiveMode(id, curScreenInfo_);
|
||||
ROSEN_LOGI("RSHardwareProcessor::Init screen w:%{public}d, w:%{public}d",
|
||||
curScreenInfo.GetScreenWidth(), curScreenInfo.GetScreenHeight());
|
||||
curScreenInfo_.GetScreenWidth(), curScreenInfo_.GetScreenHeight());
|
||||
IRect damageRect;
|
||||
damageRect.x = 0;
|
||||
damageRect.y = 0;
|
||||
damageRect.w = curScreenInfo_.GetScreenWidth();
|
||||
damageRect.h = curScreenInfo_.GetScreenHeight();
|
||||
output_->SetOutputDamage(1, damageRect);
|
||||
}
|
||||
|
||||
void RSHardwareProcessor::PostProcess()
|
||||
@ -68,7 +80,7 @@ void RSHardwareProcessor::ProcessSurface(RSSurfaceRenderNode &node)
|
||||
RSProcessor::SpecialTask task = [] () -> void{};
|
||||
bool ret = ConsumeAndUpdateBuffer(node, task, cbuffer);
|
||||
if (!ret) {
|
||||
ROSEN_LOGE("RsDebug RSCompatibleProcessor::ProcessSurface consume buffer fail");
|
||||
ROSEN_LOGE("RsDebug RSHardwareProcessor::ProcessSurface consume buffer fail");
|
||||
return;
|
||||
}
|
||||
ComposeInfo info = {
|
||||
@ -99,7 +111,7 @@ void RSHardwareProcessor::ProcessSurface(RSSurfaceRenderNode &node)
|
||||
void RSHardwareProcessor::Redraw(sptr<Surface>& surface, const struct PrepareCompleteParam& param, void* data)
|
||||
{
|
||||
if (!param.needFlushFramebuffer) {
|
||||
ROSEN_LOGE("RSHardwareProcessor::Redraw: no need to flush Framebuffer.");
|
||||
ROSEN_LOGI("RsDebug RSHardwareProcessor::Redraw no need to flush frame buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -107,9 +119,10 @@ void RSHardwareProcessor::Redraw(sptr<Surface>& surface, const struct PrepareCom
|
||||
ROSEN_LOGE("RSHardwareProcessor::Redraw: surface is null.");
|
||||
return;
|
||||
}
|
||||
ROSEN_LOGI("RsDebug RSHardwareProcessor::Redraw flush frame buffer start");
|
||||
BufferRequestConfig requestConfig = {
|
||||
.width = curScreenInfo.GetScreenWidth(),
|
||||
.height = curScreenInfo.GetScreenHeight(),
|
||||
.width = curScreenInfo_.GetScreenWidth(),
|
||||
.height = curScreenInfo_.GetScreenHeight(),
|
||||
.strideAlignment = 0x8,
|
||||
.format = PIXEL_FMT_BGRA_8888, // [TODO] different soc need different format
|
||||
.usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA,
|
||||
@ -120,23 +133,25 @@ void RSHardwareProcessor::Redraw(sptr<Surface>& surface, const struct PrepareCom
|
||||
ROSEN_LOGE("RSHardwareProcessor::Redraw: canvas is null.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto layer : param.layers) {
|
||||
ROSEN_LOGE("RsDebug RSHardwareProcessor::Redraw layer composition Type:%d", layer->GetCompositionType());
|
||||
if (layer == nullptr || layer->GetCompositionType() == CompositionType::COMPOSITION_DEVICE) {
|
||||
std::vector<LayerInfoPtr>::const_reverse_iterator iter = param.layers.rbegin();
|
||||
for (; iter != param.layers.rend(); ++iter) {
|
||||
ROSEN_LOGD("RsDebug RSHardwareProcessor::Redraw layer composition Type:%d", (*iter)->GetCompositionType());
|
||||
if ((*iter) == nullptr || (*iter)->GetCompositionType() == CompositionType::COMPOSITION_DEVICE) {
|
||||
continue;
|
||||
}
|
||||
SkMatrix matrix;
|
||||
matrix.reset();
|
||||
RsRenderServiceUtil::DrawBuffer(canvas.get(), matrix, layer->GetBuffer(), layer->GetLayerSize().x, layer->GetLayerSize().y,
|
||||
layer->GetLayerSize().w, layer->GetLayerSize().h);
|
||||
ROSEN_LOGE("RsDebug RSHardwareProcessor::Redraw layer [%d %d %d %d]", (*iter)->GetLayerSize().x,
|
||||
(*iter)->GetLayerSize().y, (*iter)->GetLayerSize().w, (*iter)->GetLayerSize().h);
|
||||
RsRenderServiceUtil::DrawBuffer(canvas.get(), matrix, (*iter)->GetBuffer(), (*iter)->GetLayerSize().x,
|
||||
(*iter)->GetLayerSize().y, (*iter)->GetLayerSize().w, (*iter)->GetLayerSize().h);
|
||||
}
|
||||
BufferFlushConfig flushConfig = {
|
||||
.damage = {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.w = curScreenInfo.GetScreenWidth(),
|
||||
.h = curScreenInfo.GetScreenHeight(),
|
||||
.w = curScreenInfo_.GetScreenWidth(),
|
||||
.h = curScreenInfo_.GetScreenHeight(),
|
||||
},
|
||||
};
|
||||
FlushBuffer(surface, flushConfig);
|
||||
|
@ -45,7 +45,7 @@ private:
|
||||
void Redraw(sptr<Surface>& surface, const struct PrepareCompleteParam& param, void* data);
|
||||
HdiBackend* backend_ = nullptr;
|
||||
sptr<RSScreenManager> screenManager_;
|
||||
RSScreenModeInfo curScreenInfo;
|
||||
RSScreenModeInfo curScreenInfo_;
|
||||
std::shared_ptr<HdiOutput> output_;
|
||||
LayerAlpha alpha_ = { .enPixelAlpha = true };
|
||||
std::vector<LayerInfoPtr> layers_;
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "unique_fd.h"
|
||||
#include <sync_fence.h>
|
||||
|
||||
#include "pipeline/rs_main_thread.h"
|
||||
#include "pipeline/rs_processor.h"
|
||||
@ -28,7 +29,12 @@ std::unique_ptr<SkCanvas> RSProcessor::CreateCanvas(sptr<Surface> producerSurfac
|
||||
if (ret != SURFACE_ERROR_OK || buffer_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sptr<SyncFence> tempFence = new SyncFence(releaseFence_);
|
||||
int res = tempFence->Wait(3000);
|
||||
if (res < 0) {
|
||||
ROSEN_LOGE("RsDebug RSProcessor::CreateCanvas this buffer is not available");
|
||||
//TODO deal with the buffer is not available
|
||||
}
|
||||
auto addr = static_cast<uint32_t*>(buffer_->GetVirAddr());
|
||||
if (addr == nullptr) {
|
||||
return nullptr;
|
||||
@ -64,14 +70,13 @@ bool RSProcessor::ConsumeAndUpdateBuffer(RSSurfaceRenderNode& node, SpecialTask&
|
||||
int64_t timestamp = 0;
|
||||
Rect damage;
|
||||
auto sret = surfaceConsumer->AcquireBuffer(buffer, fence, timestamp, damage);
|
||||
UniqueFd fenceFd(fence);
|
||||
if (!buffer || sret != OHOS::SURFACE_ERROR_OK) {
|
||||
ROSEN_LOGE("RSProcessor::ProcessSurface: AcquireBuffer failed!");
|
||||
return false;
|
||||
}
|
||||
task();
|
||||
node.SetBuffer(buffer);
|
||||
node.SetFence(fenceFd.Release());
|
||||
node.SetFence(fence);
|
||||
if (node.ReduceAvailableBuffer() >= 1) {
|
||||
if (auto mainThread = RSMainThread::Instance()) {
|
||||
mainThread->RequestNextVSync();
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "pipeline/rs_surface_capture_task.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "rs_trace.h"
|
||||
#include "screen_manager/screen_types.h"
|
||||
|
||||
namespace OHOS {
|
||||
@ -212,9 +213,12 @@ void RSRenderService::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status
|
||||
void RSRenderService::TakeSurfaceCapture(NodeId id, sptr<RSISurfaceCaptureCallback> callback)
|
||||
{
|
||||
std::function<void()> captureTask = [callback, id]() -> void {
|
||||
ROSEN_LOGD("RSRenderService::TakeSurfaceCapture callback->OnSurfaceCapture nodeId:[%llu]", id);
|
||||
ROSEN_TRACE_BEGIN(BYTRACE_TAG_GRAPHIC_AGP, "RSRenderService::TakeSurfaceCapture");
|
||||
RSSurfaceCaptureTask task(id);
|
||||
std::unique_ptr<Media::PixelMap> pixelmap = task.Run();
|
||||
callback->OnSurfaceCapture(id, pixelmap.get());
|
||||
ROSEN_TRACE_END(BYTRACE_TAG_GRAPHIC_AGP);
|
||||
};
|
||||
mainThread_->PostTask(captureTask);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <window_option.h>
|
||||
#include <window.h>
|
||||
|
||||
#include "common/rs_obj_abs_geometry.h"
|
||||
#include "pipeline/rs_base_render_node.h"
|
||||
#include "pipeline/rs_display_render_node.h"
|
||||
#include "pipeline/rs_processor.h"
|
||||
@ -64,6 +65,23 @@ void RSRenderServiceVisitor::ProcessBaseRenderNode(RSBaseRenderNode &node)
|
||||
void RSRenderServiceVisitor::PrepareDisplayRenderNode(RSDisplayRenderNode &node)
|
||||
{
|
||||
SortZOrder(node);
|
||||
for (auto child : node.GetChildren()) {
|
||||
auto existingChild = child.lock();
|
||||
if (!existingChild) {
|
||||
ROSEN_LOGI("RSRenderServiceVisitor::PrepareDisplayRenderNode this child haven't existed");
|
||||
continue;
|
||||
}
|
||||
auto surfaceChild = existingChild->ReinterpretCastTo<RSSurfaceRenderNode>();
|
||||
if (!surfaceChild) {
|
||||
ROSEN_LOGI("RSRenderServiceVisitor::PrepareDisplayRenderNode this child is not SurfaceNode");
|
||||
continue;
|
||||
}
|
||||
auto childGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(
|
||||
surfaceChild->GetRenderProperties().GetBoundsGeometry());
|
||||
if (childGeoPtr != nullptr) {
|
||||
childGeoPtr->UpdateByMatrixFromParent(nullptr);
|
||||
}
|
||||
}
|
||||
PrepareBaseRenderNode(node);
|
||||
}
|
||||
|
||||
@ -104,6 +122,32 @@ void RSRenderServiceVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode &node)
|
||||
void RSRenderServiceVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode &node)
|
||||
{
|
||||
SortZOrder(node);
|
||||
|
||||
auto currentGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(
|
||||
node.GetRenderProperties().GetBoundsGeometry());
|
||||
if (currentGeoPtr != nullptr) {
|
||||
currentGeoPtr->UpdateByMatrixFromRenderThread(node.GetMatrix());
|
||||
currentGeoPtr->UpdateByMatrixFromSelf();
|
||||
}
|
||||
|
||||
for (auto child : node.GetChildren()) {
|
||||
auto existingChild = child.lock();
|
||||
if (!existingChild) {
|
||||
ROSEN_LOGI("RSRenderServiceVisitor::PrepareSurfaceRenderNode this child haven't existed");
|
||||
continue;
|
||||
}
|
||||
auto surfaceChild = existingChild->ReinterpretCastTo<RSSurfaceRenderNode>();
|
||||
if (!surfaceChild) {
|
||||
ROSEN_LOGI("RSRenderServiceVisitor::PrepareSurfaceRenderNode this child is not SurfaceNode");
|
||||
continue;
|
||||
}
|
||||
auto childGeoPtr = std::static_pointer_cast<RSObjAbsGeometry>(
|
||||
surfaceChild->GetRenderProperties().GetBoundsGeometry());
|
||||
if (childGeoPtr != nullptr) {
|
||||
childGeoPtr->UpdateByMatrixFromParent(currentGeoPtr);
|
||||
}
|
||||
}
|
||||
PrepareBaseRenderNode(node);
|
||||
}
|
||||
|
||||
void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode &node)
|
||||
@ -113,6 +157,7 @@ void RSRenderServiceVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode &node)
|
||||
return;
|
||||
}
|
||||
processor_->ProcessSurface(node);
|
||||
ProcessBaseRenderNode(node);
|
||||
}
|
||||
|
||||
void RSRenderServiceVisitor::SortZOrder(RSBaseRenderNode &node)
|
||||
|
@ -15,16 +15,58 @@
|
||||
|
||||
#include "pipeline/rs_surface_capture_task.h"
|
||||
#include "pipeline/rs_main_thread.h"
|
||||
#include "pipeline/rs_base_render_node.h"
|
||||
#include "pipeline/rs_display_render_node.h"
|
||||
#include "pipeline/rs_render_service_util.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "platform/drawing/rs_surface.h"
|
||||
#include "screen_manager/rs_screen_manager.h"
|
||||
#include "screen_manager/rs_screen_mode_info.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::Run()
|
||||
{
|
||||
auto node = RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode<RSSurfaceRenderNode>(nodeId_);
|
||||
std::shared_ptr<RSBaseRenderNode> node =
|
||||
RSMainThread::Instance()->GetContext().GetNodeMap().GetRenderNode<RSBaseRenderNode>(nodeId_);
|
||||
if (node == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask: node == nullptr\n");
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::Run: node is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<Media::PixelMap> pixelmap;
|
||||
std::shared_ptr<RSSurfaceCaptureVisitor> visitor = std::make_shared<RSSurfaceCaptureVisitor>();
|
||||
if (node->GetType() == RSRenderNodeType::SURFACE_NODE) {
|
||||
ROSEN_LOGI("RSSurfaceCaptureTask::Run: Into SURFACE_NODE SurfaceRenderNodeId:[%llu]", node->GetId());
|
||||
pixelmap = CreatePixelMapBySurfaceNode(std::static_pointer_cast<RSSurfaceRenderNode>(node));
|
||||
visitor->IsDisplayNode(false);
|
||||
} else if (node->GetType() == RSRenderNodeType::DISPLAY_NODE) {
|
||||
ROSEN_LOGI("RSSurfaceCaptureTask::Run: Into DISPLAY_NODE DisplayRenderNodeId:[%llu]", node->GetId());
|
||||
pixelmap = CreatePixelMapByDisplayNode(std::static_pointer_cast<RSDisplayRenderNode>(node));
|
||||
visitor->IsDisplayNode(true);
|
||||
} else {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::Run: Invalid RSRenderNodeType!");
|
||||
return nullptr;
|
||||
}
|
||||
if (pixelmap == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::Run: pixelmap == nullptr!");
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<SkCanvas> canvas = CreateCanvas(pixelmap);
|
||||
if (canvas == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::Run: canvas is nullptr!");
|
||||
return nullptr;
|
||||
}
|
||||
visitor->SetCanvas(std::move(canvas));
|
||||
node->Process(visitor);
|
||||
return pixelmap;
|
||||
}
|
||||
|
||||
std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode(
|
||||
std::shared_ptr<RSSurfaceRenderNode> node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
ROSEN_LOGE("CreatePixelMapBySurfaceNode: node == nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
int pixmapWidth = node->GetRenderProperties().GetBoundsWidth();
|
||||
@ -32,39 +74,91 @@ std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::Run()
|
||||
Media::InitializationOptions opts;
|
||||
opts.size.width = pixmapWidth;
|
||||
opts.size.height = pixmapHeight;
|
||||
std::unique_ptr<Media::PixelMap> pixelmap = Media::PixelMap::Create(opts);
|
||||
ROSEN_LOGD("RSSurfaceCaptureTask::CreatePixelMapBySurfaceNode: pixelmap width is [%u], height is [%u].",
|
||||
pixmapWidth, pixmapHeight);
|
||||
return Media::PixelMap::Create(opts);
|
||||
}
|
||||
|
||||
std::unique_ptr<Media::PixelMap> RSSurfaceCaptureTask::CreatePixelMapByDisplayNode(
|
||||
std::shared_ptr<RSDisplayRenderNode> node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: node is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
int screenId = node->GetScreenId();
|
||||
RSScreenModeInfo screenModeInfo;
|
||||
sptr<RSScreenManager> screenManager = CreateOrGetScreenManager();
|
||||
if (!screenManager) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: screenManager is nullptr!");
|
||||
return nullptr;
|
||||
}
|
||||
screenManager->GetScreenActiveMode(screenId, screenModeInfo);
|
||||
int pixmapWidth = screenModeInfo.GetScreenWidth();
|
||||
int pixmapHeight = screenModeInfo.GetScreenHeight();
|
||||
Media::InitializationOptions opts;
|
||||
opts.size.width = pixmapWidth;
|
||||
opts.size.height = pixmapHeight;
|
||||
ROSEN_LOGD("RSSurfaceCaptureTask::CreatePixelMapByDisplayNode: pixelmap width is [%u], height is [%u].",
|
||||
pixmapWidth, pixmapHeight);
|
||||
return Media::PixelMap::Create(opts);
|
||||
}
|
||||
|
||||
std::unique_ptr<SkCanvas> RSSurfaceCaptureTask::CreateCanvas(const std::unique_ptr<Media::PixelMap>& pixelmap)
|
||||
{
|
||||
if (pixelmap == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask: pixelmap == nullptr\n");
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::CreateCanvas: pixelmap == nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
auto address = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
|
||||
if (address == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask: address == nullptr\n");
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::CreateCanvas: address == nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
SkImageInfo info = SkImageInfo::Make(pixmapWidth, pixmapHeight,
|
||||
SkImageInfo info = SkImageInfo::Make(pixelmap->GetWidth(), pixelmap->GetHeight(),
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(info, address, pixelmap->GetRowBytes());
|
||||
return SkCanvas::MakeRasterDirect(info, address, pixelmap->GetRowBytes());
|
||||
}
|
||||
|
||||
// get surface capture
|
||||
sptr<OHOS::SurfaceBuffer> buffer = node->GetBuffer();
|
||||
if (buffer == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask: buffer == nullptr\n");
|
||||
return nullptr;
|
||||
void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::SetCanvas(std::unique_ptr<SkCanvas> canvas)
|
||||
{
|
||||
if (canvas == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::SetCanvas: address == nullptr");
|
||||
return;
|
||||
}
|
||||
auto addr = static_cast<uint32_t*>(buffer->GetVirAddr());
|
||||
if (addr == nullptr || buffer->GetWidth() <= 0 || buffer->GetHeight() <= 0) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureTask: addr is nullptr, or buffer->GetWidth() buffer->GetHeight() is error.\n");
|
||||
return nullptr;
|
||||
canvas_ = std::move(canvas);
|
||||
}
|
||||
|
||||
void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessDisplayRenderNode(RSDisplayRenderNode &node)
|
||||
{
|
||||
ROSEN_LOGD("RsDebug RSSurfaceCaptureVisitor::ProcessDisplayRenderNode child size:[%d]", node.GetChildren().size());
|
||||
for (auto child : node.GetChildren()) {
|
||||
auto existingChild = child.lock();
|
||||
if (!existingChild) {
|
||||
ROSEN_LOGD("RSSurfaceCaptureVisitor::ProcessDisplayRenderNode this child haven't existed");
|
||||
continue;
|
||||
}
|
||||
existingChild->Process(shared_from_this());
|
||||
}
|
||||
SkImageInfo layerInfo = SkImageInfo::Make(buffer->GetWidth(), buffer->GetHeight(),
|
||||
kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
SkPixmap skpixmap(layerInfo, addr, buffer->GetSize() / buffer->GetHeight());
|
||||
SkBitmap skbitmap;
|
||||
if (skbitmap.installPixels(skpixmap)) {
|
||||
canvas->drawBitmapRect(skbitmap, SkRect::MakeXYWH(0, 0, buffer->GetWidth(), buffer->GetHeight()), nullptr);
|
||||
}
|
||||
|
||||
void RSSurfaceCaptureTask::RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode &node)
|
||||
{
|
||||
if (isDisplayNode_) {
|
||||
RsRenderServiceUtil::DrawBuffer(canvas_.get(), node.GetMatrix(), node.GetBuffer(), node);
|
||||
} else {
|
||||
float scaleX = node.GetRenderProperties().GetBoundsWidth();
|
||||
float scaleY = node.GetRenderProperties().GetBoundsHeight();
|
||||
RsRenderServiceUtil::DrawBuffer(canvas_.get(), node.GetMatrix(), node.GetBuffer(), 0, 0, scaleX, scaleY);
|
||||
}
|
||||
for (auto child : node.GetChildren()) {
|
||||
auto existingChild = child.lock();
|
||||
if (!existingChild) {
|
||||
ROSEN_LOGD("RSSurfaceCaptureVisitor::ProcessSurfaceRenderNode this child haven't existed");
|
||||
continue;
|
||||
}
|
||||
existingChild->Process(shared_from_this());
|
||||
}
|
||||
return pixelmap;
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,11 @@
|
||||
#define RS_SURFACE_CAPTURE_TASK
|
||||
|
||||
#include "common/rs_common_def.h"
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "pipeline/rs_display_render_node.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
#include "pixel_map.h"
|
||||
#include "visitor/rs_node_visitor.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
@ -29,6 +33,39 @@ public:
|
||||
std::unique_ptr<Media::PixelMap> Run();
|
||||
|
||||
private:
|
||||
class RSSurfaceCaptureVisitor : public RSNodeVisitor {
|
||||
public:
|
||||
RSSurfaceCaptureVisitor() {}
|
||||
~RSSurfaceCaptureVisitor() override {}
|
||||
virtual void PrepareBaseRenderNode(RSBaseRenderNode &node) override {}
|
||||
virtual void PrepareDisplayRenderNode(RSDisplayRenderNode &node) override {}
|
||||
virtual void PrepareSurfaceRenderNode(RSSurfaceRenderNode &node) override {}
|
||||
virtual void PrepareCanvasRenderNode(RSCanvasRenderNode &node) override {}
|
||||
virtual void PrepareRootRenderNode(RSRootRenderNode& node) override {}
|
||||
virtual void ProcessBaseRenderNode(RSBaseRenderNode &node) override {}
|
||||
virtual void ProcessCanvasRenderNode(RSCanvasRenderNode& node) override {}
|
||||
virtual void ProcessRootRenderNode(RSRootRenderNode& node) override {}
|
||||
|
||||
virtual void ProcessDisplayRenderNode(RSDisplayRenderNode &node) override;
|
||||
virtual void ProcessSurfaceRenderNode(RSSurfaceRenderNode &node) override;
|
||||
void SetCanvas(std::unique_ptr<SkCanvas> canvas);
|
||||
void IsDisplayNode(bool isDisplayNode)
|
||||
{
|
||||
isDisplayNode_ = isDisplayNode;
|
||||
}
|
||||
|
||||
private:
|
||||
void DrawSurface(RSSurfaceRenderNode &node);
|
||||
std::unique_ptr<SkCanvas> canvas_ = nullptr;
|
||||
bool isDisplayNode_ = false;
|
||||
};
|
||||
|
||||
std::unique_ptr<SkCanvas> CreateCanvas(const std::unique_ptr<Media::PixelMap>& pixelmap);
|
||||
|
||||
std::unique_ptr<Media::PixelMap> CreatePixelMapBySurfaceNode(std::shared_ptr<RSSurfaceRenderNode> node);
|
||||
|
||||
std::unique_ptr<Media::PixelMap> CreatePixelMapByDisplayNode(std::shared_ptr<RSDisplayRenderNode> node);
|
||||
|
||||
NodeId nodeId_;
|
||||
};
|
||||
} // namespace Rosen
|
||||
|
@ -111,21 +111,15 @@ ohos_shared_library("librender_service_base") {
|
||||
"src/screen_manager/rs_screen_props.cpp",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//foundation/multimedia/image_standard/interfaces/innerkits:image_native",
|
||||
]
|
||||
|
||||
public_deps = [
|
||||
"src/platform:platform",
|
||||
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
|
||||
"//foundation/multimedia/image_standard/interfaces/innerkits:image_native",
|
||||
]
|
||||
|
||||
part_name = "graphic_standard"
|
||||
subsystem_name = "graphic"
|
||||
|
||||
if (enable_debug) {
|
||||
defines += [ "ROSEN_DEBUG" ]
|
||||
}
|
||||
if (rosen_is_win) {
|
||||
defines += [ "_USE_MATH_DEFINES" ]
|
||||
}
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
import("//build/ohos.gni")
|
||||
|
||||
enable_debug = true
|
||||
|
||||
rosen_is_ohos = current_os == "ohos"
|
||||
rosen_is_android = current_os == "android"
|
||||
rosen_is_ios = current_os == "ios" || current_os == "tvos"
|
||||
|
@ -30,13 +30,13 @@ enum RSRootNodeCommandType : uint16_t {
|
||||
class RootNodeCommandHelper {
|
||||
public:
|
||||
static void Create(RSContext& context, NodeId id);
|
||||
static void AttachRSSurface(
|
||||
RSContext& context, NodeId id, std::shared_ptr<RSSurface> rsSurface, int width, int height);
|
||||
static void AttachRSSurfaceNode(
|
||||
RSContext& context, NodeId id, NodeId surfaceNodeId, int width, int height);
|
||||
};
|
||||
|
||||
ADD_COMMAND(RSRootNodeCreate, ARG(ROOT_NODE, ROOT_NODE_CREATE, RootNodeCommandHelper::Create, NodeId))
|
||||
ADD_COMMAND(RSRootNodeAttachRSSurface, ARG(ROOT_NODE, ROOT_NODE_ATTACH, RootNodeCommandHelper::AttachRSSurface, NodeId,
|
||||
std::shared_ptr<RSSurface>, int, int))
|
||||
ADD_COMMAND(RSRootNodeAttachRSSurfaceNode, ARG(ROOT_NODE, ROOT_NODE_ATTACH, RootNodeCommandHelper::AttachRSSurfaceNode,
|
||||
NodeId, NodeId, int, int))
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -28,6 +28,7 @@ enum RSSurfaceNodeCommandType : uint16_t {
|
||||
SURFACE_NODE_SET_MATRIX,
|
||||
SURFACE_NODE_SET_ALPHA,
|
||||
SURFACE_NODE_SET_PARENT_SURFACE,
|
||||
SURFACE_NODE_REMOVE_SELF,
|
||||
};
|
||||
|
||||
class SurfaceNodeCommandHelper {
|
||||
@ -35,7 +36,8 @@ public:
|
||||
static void Create(RSContext& context, NodeId nodeId);
|
||||
static void SetMatrix(RSContext& context, NodeId nodeId, SkMatrix matrix);
|
||||
static void SetAlpha(RSContext& context, NodeId nodeId, float alpha);
|
||||
static void SetParentSurface(RSContext& context, NodeId nodeId, NodeId parent);
|
||||
static void SetParentSurface(RSContext& context, NodeId nodeId, NodeId parentId);
|
||||
static void RemoveSelf(RSContext& context, NodeId nodeId);
|
||||
};
|
||||
|
||||
ADD_COMMAND(RSSurfaceNodeCreate, ARG(SURFACE_NODE, SURFACE_NODE_CREATE, SurfaceNodeCommandHelper::Create, NodeId))
|
||||
@ -45,6 +47,8 @@ ADD_COMMAND(
|
||||
RSSurfaceNodeSetAlpha, ARG(SURFACE_NODE, SURFACE_NODE_SET_ALPHA, SurfaceNodeCommandHelper::SetAlpha, NodeId, float))
|
||||
ADD_COMMAND(RSSurfaceNodeSetParentSurface,
|
||||
ARG(SURFACE_NODE, SURFACE_NODE_SET_PARENT_SURFACE, SurfaceNodeCommandHelper::SetParentSurface, NodeId, NodeId))
|
||||
ADD_COMMAND(RSSurfaceNodeRemoveSelf,
|
||||
ARG(SURFACE_NODE, SURFACE_NODE_REMOVE_SELF, SurfaceNodeCommandHelper::RemoveSelf, NodeId))
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -32,6 +32,12 @@ public:
|
||||
~RSObjAbsGeometry() override;
|
||||
void UpdateMatrix(const Matrix3f& matrix);
|
||||
void UpdateMatrix(const std::shared_ptr<RSObjAbsGeometry>& parent, float offsetX, float offsetY);
|
||||
|
||||
// Using by RenderService
|
||||
void UpdateByMatrixFromParent(const std::shared_ptr<RSObjAbsGeometry>& parent);
|
||||
void UpdateByMatrixFromRenderThread(const SkMatrix& skMatrix);
|
||||
void UpdateByMatrixFromSelf();
|
||||
|
||||
const RectI& GetAbsRect() const
|
||||
{
|
||||
return absRect_;
|
||||
@ -41,6 +47,12 @@ public:
|
||||
{
|
||||
return matrix_;
|
||||
}
|
||||
|
||||
const SkMatrix& GetAbsMatrix() const
|
||||
{
|
||||
return absMatrix_;
|
||||
}
|
||||
|
||||
bool IsPointInHotZone(const float x, const float y) const;
|
||||
|
||||
private:
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
virtual void Prepare(const std::shared_ptr<RSNodeVisitor>& visitor) override;
|
||||
virtual void Process(const std::shared_ptr<RSNodeVisitor>& visitor) override;
|
||||
|
||||
void AttachRSSurface(std::shared_ptr<RSSurface> rsSurface, int width, int height);
|
||||
void AttachRSSurfaceNode(NodeId SurfaceNodeId, int width, int height);
|
||||
|
||||
RSRenderNodeType GetType() const override
|
||||
{
|
||||
@ -37,12 +37,18 @@ public:
|
||||
}
|
||||
|
||||
std::shared_ptr<RSSurface> GetSurface();
|
||||
NodeId GetRSSurfaceNodeId();
|
||||
int32_t GetSurfaceWidth() const;
|
||||
int32_t GetSurfaceHeight() const;
|
||||
|
||||
void AddSurfaceRenderNode(NodeId id);
|
||||
void ClearSurfaceNodeInRS();
|
||||
private:
|
||||
int32_t surfaceWidth_ = 0;
|
||||
int32_t surfaceHeight_ = 0;
|
||||
std::shared_ptr<RSSurface> rsSurface_ = nullptr;
|
||||
NodeId surfaceNodeId_;
|
||||
std::vector<NodeId> childSurfaceNodeId_;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -177,11 +177,11 @@ public:
|
||||
bool GetVisible() const;
|
||||
bool SetId(NodeId id);
|
||||
|
||||
private:
|
||||
const std::shared_ptr<RSObjGeometry>& GetBoundsGeometry() const;
|
||||
const std::shared_ptr<RSObjGeometry>& GetFrameGeometry() const;
|
||||
bool UpdateGeometry(const RSProperties* parent, bool dirtyFlag);
|
||||
|
||||
private:
|
||||
void SetDirty();
|
||||
void ResetDirty();
|
||||
bool IsDirty() const;
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
void AddCommand(std::unique_ptr<RSCommand>& command, bool isRenderServiceCommand = false);
|
||||
|
||||
void FlushImplicitTransaction();
|
||||
void FlushImplicitRemoteTransaction();
|
||||
|
||||
void ExecuteSynchronousTask(const std::shared_ptr<RSSyncTask>& task, bool isRenderServiceTask = false);
|
||||
private:
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "command/rs_root_node_command.h"
|
||||
|
||||
#include "pipeline/rs_root_render_node.h"
|
||||
#include "pipeline/rs_surface_render_node.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
@ -26,16 +27,12 @@ void RootNodeCommandHelper::Create(RSContext& context, NodeId id)
|
||||
context.GetNodeMap().RegisterRenderNode(node);
|
||||
}
|
||||
|
||||
void RootNodeCommandHelper::AttachRSSurface(
|
||||
RSContext& context, NodeId id, std::shared_ptr<RSSurface> rsSurface, int width, int height)
|
||||
void RootNodeCommandHelper::AttachRSSurfaceNode(
|
||||
RSContext& context, NodeId id, NodeId surfaceNodeId, int width, int height)
|
||||
{
|
||||
if (auto node = context.GetNodeMap().GetRenderNode<RSRootRenderNode>(id)) {
|
||||
node->AttachRSSurface(rsSurface, width, height);
|
||||
if (rsSurface == nullptr) {
|
||||
context.GetGlobalRootRenderNode()->RemoveChild(node);
|
||||
} else {
|
||||
context.GetGlobalRootRenderNode()->AddChild(node);
|
||||
}
|
||||
node->AttachRSSurfaceNode(surfaceNodeId, width, height);
|
||||
context.GetGlobalRootRenderNode()->AddChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,11 +46,20 @@ void SurfaceNodeCommandHelper::SetParentSurface(RSContext& context, NodeId id, N
|
||||
auto& nodeMap = context.GetNodeMap();
|
||||
auto node = nodeMap.GetRenderNode<RSSurfaceRenderNode>(id);
|
||||
auto parent = nodeMap.GetRenderNode<RSBaseRenderNode>(parentId);
|
||||
if (node && parent && parentId != node->GetParentId()) {
|
||||
if (node && parent) {
|
||||
node->SetParentId(parentId, false);
|
||||
parent->AddChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceNodeCommandHelper::RemoveSelf(RSContext& context, NodeId id)
|
||||
{
|
||||
auto& nodeMap = context.GetNodeMap();
|
||||
auto node = nodeMap.GetRenderNode<RSBaseRenderNode>(id);
|
||||
if (node) {
|
||||
node->RemoveFromTree();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -62,6 +62,32 @@ void RSObjAbsGeometry::UpdateMatrix(const std::shared_ptr<RSObjAbsGeometry>& par
|
||||
SetAbsRect();
|
||||
}
|
||||
|
||||
void RSObjAbsGeometry::UpdateByMatrixFromParent(const std::shared_ptr<RSObjAbsGeometry>& parent)
|
||||
{
|
||||
absMatrix_.reset();
|
||||
if (parent != nullptr) {
|
||||
absMatrix_ = parent->absMatrix_;
|
||||
}
|
||||
}
|
||||
|
||||
void RSObjAbsGeometry::UpdateByMatrixFromRenderThread(const SkMatrix& skMatrix)
|
||||
{
|
||||
absMatrix_.preConcat(skMatrix);
|
||||
}
|
||||
|
||||
void RSObjAbsGeometry::UpdateByMatrixFromSelf()
|
||||
{
|
||||
matrix_.reset();
|
||||
if (!trans_ || (ROSEN_EQ(z_ + trans_->translateZ_, 0.f) && ROSEN_EQ(trans_->rotationX_, 0.f) &&
|
||||
ROSEN_EQ(trans_->rotationY_, 0.f) && trans_->quaternion_.IsIdentity())) {
|
||||
UpdateAbsMatrix2D();
|
||||
} else {
|
||||
UpdateAbsMatrix3D();
|
||||
}
|
||||
absMatrix_.preConcat(matrix_);
|
||||
SetAbsRect();
|
||||
}
|
||||
|
||||
void RSObjAbsGeometry::UpdateAbsMatrix2D()
|
||||
{
|
||||
if (!trans_) {
|
||||
|
@ -31,9 +31,8 @@ void RSSurfaceCaptureCallbackProxy::OnSurfaceCapture(NodeId id, Media::PixelMap*
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
|
||||
if (!data.WriteInterfaceToken(RSISurfaceCaptureCallback::GetDescriptor())) {
|
||||
ROSEN_LOGE("SurfaceCaptureCallbackProxy: data.WriteInterfaceToken error\n");
|
||||
ROSEN_LOGE("SurfaceCaptureCallbackProxy: data.WriteInterfaceToken error");
|
||||
return;
|
||||
}
|
||||
data.WriteUint64(id);
|
||||
@ -41,7 +40,7 @@ void RSSurfaceCaptureCallbackProxy::OnSurfaceCapture(NodeId id, Media::PixelMap*
|
||||
option.SetFlags(MessageOption::TF_ASYNC);
|
||||
int32_t err = Remote()->SendRequest(RSISurfaceCaptureCallback::ON_SURFACE_CAPTURE, data, reply, option);
|
||||
if (err != NO_ERROR) {
|
||||
ROSEN_LOGE("SurfaceCaptureCallbackProxy: Remote()->SendRequest() error\n");
|
||||
ROSEN_LOGE("SurfaceCaptureCallbackProxy: Remote()->SendRequest() error");
|
||||
}
|
||||
}
|
||||
} // namespace Rosen
|
||||
|
@ -24,7 +24,7 @@ int RSSurfaceCaptureCallbackStub::OnRemoteRequest(
|
||||
{
|
||||
auto token = data.ReadInterfaceToken();
|
||||
if (token != RSISurfaceCaptureCallback::GetDescriptor()) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureCallbackStub: token ERR_INVALID_STATE\n");
|
||||
ROSEN_LOGE("RSSurfaceCaptureCallbackStub: token ERR_INVALID_STATE");
|
||||
return ERR_INVALID_STATE;
|
||||
}
|
||||
int ret = ERR_NONE;
|
||||
@ -32,10 +32,6 @@ int RSSurfaceCaptureCallbackStub::OnRemoteRequest(
|
||||
case ON_SURFACE_CAPTURE: {
|
||||
NodeId id = data.ReadUint64();
|
||||
auto pixelmap = data.ReadParcelable<OHOS::Media::PixelMap>();
|
||||
if (pixelmap == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceCaptureCallbackStub: pixelmap == nullptr!\n");
|
||||
return ERR_NULL_OBJECT;
|
||||
}
|
||||
OnSurfaceCapture(id, pixelmap);
|
||||
break;
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "platform/drawing/rs_surface.h"
|
||||
#include "visitor/rs_node_visitor.h"
|
||||
#include "command/rs_surface_node_command.h"
|
||||
#include "transaction/rs_transaction_proxy.h"
|
||||
#ifdef ROSEN_OHOS
|
||||
#include <surface.h>
|
||||
|
||||
@ -28,9 +30,10 @@ RSRootRenderNode::RSRootRenderNode(NodeId id) : RSCanvasRenderNode(id) {}
|
||||
|
||||
RSRootRenderNode::~RSRootRenderNode() {}
|
||||
|
||||
void RSRootRenderNode::AttachRSSurface(std::shared_ptr<RSSurface> rsSurface, int width, int height)
|
||||
|
||||
void RSRootRenderNode::AttachRSSurfaceNode(NodeId surfaceNodeId, int width, int height)
|
||||
{
|
||||
rsSurface_ = rsSurface;
|
||||
surfaceNodeId_ = surfaceNodeId;
|
||||
surfaceWidth_ = width;
|
||||
surfaceHeight_ = height;
|
||||
}
|
||||
@ -50,6 +53,28 @@ std::shared_ptr<RSSurface> RSRootRenderNode::GetSurface()
|
||||
return rsSurface_;
|
||||
}
|
||||
|
||||
NodeId RSRootRenderNode::GetRSSurfaceNodeId()
|
||||
{
|
||||
return surfaceNodeId_;
|
||||
}
|
||||
|
||||
void RSRootRenderNode::AddSurfaceRenderNode(NodeId id)
|
||||
{
|
||||
childSurfaceNodeId_.push_back(id);
|
||||
}
|
||||
|
||||
void RSRootRenderNode::ClearSurfaceNodeInRS()
|
||||
{
|
||||
for (auto childId : childSurfaceNodeId_) {
|
||||
std::unique_ptr<RSCommand> command = std::make_unique<RSSurfaceNodeRemoveSelf>(childId);
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
if (transactionProxy != nullptr) {
|
||||
transactionProxy->AddCommand(command, true);
|
||||
}
|
||||
}
|
||||
childSurfaceNodeId_.clear();
|
||||
}
|
||||
|
||||
void RSRootRenderNode::Prepare(const std::shared_ptr<RSNodeVisitor>& visitor)
|
||||
{
|
||||
visitor->PrepareRootRenderNode(*this);
|
||||
|
@ -111,9 +111,6 @@ float RSSurfaceRenderNode::GetAlpha() const
|
||||
|
||||
void RSSurfaceRenderNode::SetParentId(NodeId parentId, bool sendMsg)
|
||||
{
|
||||
if (parentId_ == parentId) {
|
||||
return;
|
||||
}
|
||||
parentId_ = parentId;
|
||||
if (!sendMsg) {
|
||||
return;
|
||||
@ -125,8 +122,7 @@ void RSSurfaceRenderNode::SetParentId(NodeId parentId, bool sendMsg)
|
||||
if (node == nullptr) {
|
||||
return;
|
||||
} else if (auto rootnode = node->ReinterpretCastTo<RSRootRenderNode>()) {
|
||||
// TODO: get surface from rootnode
|
||||
command = std::make_unique<RSSurfaceNodeSetParentSurface>(GetId(), rootnode->GetId());
|
||||
command = std::make_unique<RSSurfaceNodeSetParentSurface>(GetId(), rootnode->GetRSSurfaceNodeId());
|
||||
break;
|
||||
} else if (auto surfaceNode = node->ReinterpretCastTo<RSSurfaceRenderNode>()) {
|
||||
command = std::make_unique<RSSurfaceNodeSetParentSurface>(GetId(), surfaceNode->GetId());
|
||||
|
@ -71,6 +71,7 @@ ohos_source_set("rosen_ohos_sources") {
|
||||
"//foundation/graphic/standard:libsurface",
|
||||
"//foundation/graphic/standard:libvsync_client",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics",
|
||||
"//foundation/graphic/standard/utils:sync_fence",
|
||||
"//foundation/multimedia/image_standard/interfaces/innerkits:image_native",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
@ -35,12 +35,7 @@ void RSSurfaceFrameOhosGl::SetDamageRegion(int32_t left, int32_t top, int32_t wi
|
||||
|
||||
SkCanvas* RSSurfaceFrameOhosGl::GetCanvas()
|
||||
{
|
||||
if (renderContext_->GetCanvas() == nullptr) {
|
||||
ROSEN_LOGW("RSSurfaceFrameOhosGl::GetCanvas, GetCanvas is null recreate canvas");
|
||||
renderContext_->CreateCanvas(width_, height_);
|
||||
}
|
||||
|
||||
return renderContext_->GetCanvas();
|
||||
return renderContext_->AcquireCanvas(width_, height_);
|
||||
}
|
||||
|
||||
int32_t RSSurfaceFrameOhosGl::GetReleaseFence() const
|
||||
|
@ -13,7 +13,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "rs_surface_frame_ohos_gl.h"
|
||||
#include "rs_surface_ohos_gl.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "window.h"
|
||||
@ -28,26 +27,41 @@ RSSurfaceOhosGl::RSSurfaceOhosGl(const sptr<Surface>& producer) : RSSurfaceOhos(
|
||||
{
|
||||
}
|
||||
|
||||
RSSurfaceOhosGl::~RSSurfaceOhosGl()
|
||||
{
|
||||
DestoryNativeWindow(mWindow);
|
||||
mWindow = nullptr;
|
||||
mEglSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
std::unique_ptr<RSSurfaceFrame> RSSurfaceOhosGl::RequestFrame(int32_t width, int32_t height)
|
||||
{
|
||||
std::unique_ptr<RSSurfaceFrameOhosGl> frame = std::make_unique<RSSurfaceFrameOhosGl>(width, height);
|
||||
struct NativeWindow* nWindow = CreateNativeWindowFromSurface(&producer_);
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
NativeWindowHandleOpt(nWindow, SET_BUFFER_GEOMETRY, width, height);
|
||||
NativeWindowHandleOpt(nWindow, GET_BUFFER_GEOMETRY, &h, &w);
|
||||
|
||||
RenderContext* context = GetRenderContext();
|
||||
if (context == nullptr) {
|
||||
ROSEN_LOGE("RSSurfaceOhosGl::RequestFrame, GetRenderContext failed!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mEglSurface = context->CreateEGLSurface((EGLNativeWindowType)nWindow);
|
||||
if (mWindow == nullptr) {
|
||||
mWindow = CreateNativeWindowFromSurface(&producer_);
|
||||
mEglSurface = context->CreateEGLSurface((EGLNativeWindowType)mWindow);
|
||||
ROSEN_LOGI("RSSurfaceOhosGl: Init EglSurface %{public}p", mEglSurface);
|
||||
}
|
||||
|
||||
if (mEglSurface == EGL_NO_SURFACE) {
|
||||
ROSEN_LOGE("RSSurfaceOhosGl: Invalid eglSurface, return");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<RSSurfaceFrameOhosGl> frame = std::make_unique<RSSurfaceFrameOhosGl>(width, height);
|
||||
|
||||
NativeWindowHandleOpt(mWindow, SET_BUFFER_GEOMETRY, width, height);
|
||||
NativeWindowHandleOpt(mWindow, GET_BUFFER_GEOMETRY, &mHeight, &mWidth);
|
||||
|
||||
context->MakeCurrent(mEglSurface);
|
||||
|
||||
ROSEN_LOGD("RSSurfaceOhosGl::RequestFrame, CreateEGLSurface eglsurface is %p, \
|
||||
width is %d, height is %d", mEglSurface, w, h);
|
||||
ROSEN_LOGI("RSSurfaceOhosGl:RequestFrame, eglsurface is %p, width is %d, height is %d",
|
||||
mEglSurface, mWidth, mHeight);
|
||||
|
||||
frame->SetRenderContext(context);
|
||||
|
||||
@ -67,7 +81,7 @@ bool RSSurfaceOhosGl::FlushFrame(std::unique_ptr<RSSurfaceFrame>& frame)
|
||||
// gpu render flush
|
||||
context->RenderFrame();
|
||||
context->SwapBuffers(mEglSurface);
|
||||
ROSEN_LOGD("FlushFrame::SwapBuffers eglsurface is %p", mEglSurface);
|
||||
ROSEN_LOGD("RSSurfaceOhosGl: FlushFrame, SwapBuffers eglsurface is %p", mEglSurface);
|
||||
return true;
|
||||
}
|
||||
} // namespace Rosen
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "platform/drawing/rs_surface.h"
|
||||
#include "platform/ohos/rs_surface_ohos.h"
|
||||
#include "render_context/render_context.h"
|
||||
#include "rs_surface_frame_ohos_gl.h"
|
||||
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
@ -28,7 +30,7 @@ namespace Rosen {
|
||||
class RSSurfaceOhosGl : public RSSurfaceOhos {
|
||||
public:
|
||||
explicit RSSurfaceOhosGl(const sptr<Surface>& producer);
|
||||
~RSSurfaceOhosGl() = default;
|
||||
~RSSurfaceOhosGl();
|
||||
|
||||
bool IsValid() const override
|
||||
{
|
||||
@ -38,7 +40,10 @@ public:
|
||||
std::unique_ptr<RSSurfaceFrame> RequestFrame(int32_t width, int32_t height) override;
|
||||
bool FlushFrame(std::unique_ptr<RSSurfaceFrame>& frame) override;
|
||||
private:
|
||||
EGLSurface mEglSurface;
|
||||
EGLSurface mEglSurface = EGL_NO_SURFACE;
|
||||
struct NativeWindow* mWindow = nullptr;
|
||||
int mWidth = -1;
|
||||
int mHeight = -1;
|
||||
};
|
||||
|
||||
} // namespace Rosen
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
#include "rs_surface_ohos_raster.h"
|
||||
|
||||
#include <sync_fence.h>
|
||||
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "rs_surface_frame_ohos_raster.h"
|
||||
|
||||
@ -36,7 +38,12 @@ std::unique_ptr<RSSurfaceFrame> RSSurfaceOhosRaster::RequestFrame(int32_t width,
|
||||
ROSEN_LOGE("RSSurfaceOhosRaster::Requestframe Failed, error is : %s", SurfaceErrorStr(err).c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sptr<SyncFence> tempFence = new SyncFence(frame->releaseFence_);
|
||||
int res = tempFence->Wait(3000);
|
||||
if (res < 0) {
|
||||
ROSEN_LOGE("RsDebug RSProcessor::RequestFrame this buffer is not available");
|
||||
//TODO deal with the buffer is not available
|
||||
}
|
||||
std::unique_ptr<RSSurfaceFrame> ret(std::move(frame));
|
||||
return ret;
|
||||
}
|
||||
@ -53,7 +60,7 @@ bool RSSurfaceOhosRaster::FlushFrame(std::unique_ptr<RSSurfaceFrame>& frame)
|
||||
ROSEN_LOGE("RSSurfaceOhosRaster::Flushframe Failed, error is : %s", SurfaceErrorStr(err).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
ROSEN_LOGE("RsDebug RSSurfaceOhosRaster::FlushFrame fence:%d", oriFramePtr->releaseFence_);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -68,16 +68,22 @@ std::shared_ptr<RSSurface> RSRenderServiceClient::CreateNodeAndSurface(const RSS
|
||||
|
||||
void RSRenderServiceClient::TriggerSurfaceCaptureCallback(NodeId id, Media::PixelMap* pixelmap)
|
||||
{
|
||||
ROSEN_LOGI("RSRenderServiceClient::Into TriggerSurfaceCaptureCallback nodeId:[%llu]", id);
|
||||
std::shared_ptr<Media::PixelMap> surfaceCapture(pixelmap);
|
||||
std::shared_ptr<SurfaceCaptureCallback> callback = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
auto iter = surfaceCaptureCbMap_.find(id);
|
||||
if (iter != surfaceCaptureCbMap_.end()) {
|
||||
auto callback = iter->second;
|
||||
callback->OnSurfaceCapture(surfaceCapture);
|
||||
callback = iter->second;
|
||||
surfaceCaptureCbMap_.erase(iter);
|
||||
}
|
||||
}
|
||||
if (callback == nullptr) {
|
||||
ROSEN_LOGE("RSRenderServiceClient::TriggerSurfaceCaptureCallback: callback is nullptr!");
|
||||
return;
|
||||
}
|
||||
callback->OnSurfaceCapture(surfaceCapture);
|
||||
}
|
||||
|
||||
class SurfaceCaptureCallbackDirector : public RSSurfaceCaptureCallbackStub
|
||||
@ -100,13 +106,17 @@ bool RSRenderServiceClient::TakeSurfaceCapture(NodeId id, std::shared_ptr<Surfac
|
||||
{
|
||||
auto renderService = RSRenderServiceConnect::GetRenderService();
|
||||
if (renderService == nullptr) {
|
||||
ROSEN_LOGE("RSRenderServiceClient: renderService == nullptr!\n");
|
||||
ROSEN_LOGE("RSRenderServiceClient::TakeSurfaceCapture renderService == nullptr!");
|
||||
return false;
|
||||
}
|
||||
if (callback == nullptr) {
|
||||
ROSEN_LOGE("RSRenderServiceClient::TakeSurfaceCapture callback == nullptr!");
|
||||
return false;
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (surfaceCaptureCbMap_.count(id) != 0) {
|
||||
ROSEN_LOGW("RSRenderServiceClient: surfaceCaptureCbMap_.count(id) != 0\n");
|
||||
ROSEN_LOGW("RSRenderServiceClient::TakeSurfaceCapture surfaceCaptureCbMap_.count(id) != 0");
|
||||
return false;
|
||||
}
|
||||
surfaceCaptureCbMap_.emplace(id, callback);
|
||||
@ -115,7 +125,6 @@ bool RSRenderServiceClient::TakeSurfaceCapture(NodeId id, std::shared_ptr<Surfac
|
||||
if (surfaceCaptureCbDirector_ == nullptr) {
|
||||
surfaceCaptureCbDirector_ = new SurfaceCaptureCallbackDirector(this);
|
||||
}
|
||||
|
||||
renderService->TakeSurfaceCapture(id, surfaceCaptureCbDirector_);
|
||||
return true;
|
||||
}
|
||||
|
@ -221,10 +221,9 @@ void RSRenderServiceProxy::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus s
|
||||
void RSRenderServiceProxy::TakeSurfaceCapture(NodeId id, sptr<RSISurfaceCaptureCallback> callback)
|
||||
{
|
||||
if (callback == nullptr) {
|
||||
ROSEN_LOGE("RSRenderServiceProxy: callback == nullptr\n");
|
||||
ROSEN_LOGE("RSRenderServiceProxy::TakeSurfaceCapture callback == nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
MessageParcel data;
|
||||
MessageParcel reply;
|
||||
MessageOption option;
|
||||
@ -233,7 +232,7 @@ void RSRenderServiceProxy::TakeSurfaceCapture(NodeId id, sptr<RSISurfaceCaptureC
|
||||
data.WriteRemoteObject(callback->AsObject());
|
||||
int32_t err = Remote()->SendRequest(RSIRenderService::TAKE_SURFACE_CAPTURE, data, reply, option);
|
||||
if (err != NO_ERROR) {
|
||||
ROSEN_LOGE("RSRenderServiceProxy: Remote()->SendRequest() error.\n");
|
||||
ROSEN_LOGE("RSRenderServiceProxy::TakeSurfaceCapture Remote()->SendRequest() error.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -113,7 +113,16 @@ void RSTransactionProxy::FlushImplicitTransaction()
|
||||
}
|
||||
}
|
||||
|
||||
void RSTransactionProxy::AddCommonCommand(std::unique_ptr<RSCommand>& command)
|
||||
void RSTransactionProxy::FlushImplicitRemoteTransaction()
|
||||
{
|
||||
std::unique_lock<std::mutex> cmdLock(mutex_);
|
||||
if (renderServiceClient_ != nullptr && !implicitRemoteTransactionData_->IsEmpty()) {
|
||||
renderServiceClient_->CommitTransaction(implicitRemoteTransactionData_);
|
||||
implicitRemoteTransactionData_ = std::make_unique<RSTransactionData>();
|
||||
}
|
||||
}
|
||||
|
||||
void RSTransactionProxy::AddCommonCommand(std::unique_ptr<RSCommand> &command)
|
||||
{
|
||||
implicitCommonTransactionData_->AddCommand(command);
|
||||
}
|
||||
|
@ -93,10 +93,6 @@ ohos_source_set("render_service_client_src") {
|
||||
external_deps = [ "bytrace_standard:bytrace_core" ]
|
||||
public_deps =
|
||||
[ "$rosen_root/modules/render_service_base:librender_service_base" ]
|
||||
|
||||
if (enable_debug) {
|
||||
defines += [ "ROSEN_DEBUG" ]
|
||||
}
|
||||
}
|
||||
|
||||
ohos_shared_library("librender_service_client") {
|
||||
|
@ -72,6 +72,10 @@ RSRenderThread::RSRenderThread()
|
||||
Render();
|
||||
RS_ASYNC_TRACE_BEGIN("waiting GPU running", 1111); // 1111 means async trace code for gpu
|
||||
SendCommands();
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
if (transactionProxy != nullptr) {
|
||||
transactionProxy->FlushImplicitRemoteTransaction();
|
||||
}
|
||||
ROSEN_TRACE_END(BYTRACE_TAG_GRAPHIC_AGP);
|
||||
};
|
||||
}
|
||||
@ -116,7 +120,7 @@ void RSRenderThread::WakeUp()
|
||||
|
||||
void RSRenderThread::RecvTransactionData(std::unique_ptr<RSTransactionData>& transactionData)
|
||||
{
|
||||
StopTimer();
|
||||
// StopTimer();
|
||||
{
|
||||
std::unique_lock<std::mutex> cmdLock(cmdMutex_);
|
||||
cmds_.emplace_back(std::move(transactionData));
|
||||
@ -181,7 +185,6 @@ void RSRenderThread::OnVsync(uint64_t timestamp)
|
||||
ROSEN_TRACE_BEGIN(BYTRACE_TAG_GRAPHIC_AGP, "RSRenderThread::OnVsync");
|
||||
mValue = (mValue + 1) % 2;
|
||||
RS_TRACE_INT("Vsync-client", mValue);
|
||||
ROSEN_LOGD("RSRenderThread::OnVsync(%lld).", timestamp);
|
||||
timestamp_ = timestamp;
|
||||
StartTimer(0); // start render-loop now
|
||||
ROSEN_TRACE_END(BYTRACE_TAG_GRAPHIC_AGP);
|
||||
@ -189,7 +192,6 @@ void RSRenderThread::OnVsync(uint64_t timestamp)
|
||||
|
||||
void RSRenderThread::StartTimer(uint64_t interval)
|
||||
{
|
||||
ROSEN_LOGD("RSRenderThread StartTimer(%lld).", interval);
|
||||
if (threadHandler_ != nullptr) {
|
||||
if (timeHandle_ == nullptr) {
|
||||
timeHandle_ = RSThreadHandler::StaticCreateTask(mainFunc_);
|
||||
|
@ -25,8 +25,12 @@
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "platform/drawing/rs_surface.h"
|
||||
#include "rs_trace.h"
|
||||
#include "pipeline/rs_node_map.h"
|
||||
#include "transaction/rs_transaction_proxy.h"
|
||||
|
||||
#include "ui/rs_surface_node.h"
|
||||
#include "ui/rs_surface_extractor.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
RSRenderThreadVisitor::RSRenderThreadVisitor() : canvas_(nullptr) {}
|
||||
@ -45,6 +49,9 @@ void RSRenderThreadVisitor::PrepareBaseRenderNode(RSBaseRenderNode& node)
|
||||
void RSRenderThreadVisitor::PrepareRootRenderNode(RSRootRenderNode& node)
|
||||
{
|
||||
if (isIdle_) {
|
||||
curTreeRoot_ = &node;
|
||||
curTreeRoot_->ClearSurfaceNodeInRS();
|
||||
|
||||
dirtyManager_.Clear();
|
||||
parent_ = nullptr;
|
||||
dirtyFlag_ = false;
|
||||
@ -66,6 +73,7 @@ void RSRenderThreadVisitor::PrepareCanvasRenderNode(RSCanvasRenderNode& node)
|
||||
|
||||
void RSRenderThreadVisitor::PrepareSurfaceRenderNode(RSSurfaceRenderNode& node)
|
||||
{
|
||||
curTreeRoot_->AddSurfaceRenderNode(node.GetId());
|
||||
bool dirtyFlag = dirtyFlag_;
|
||||
dirtyFlag_ = node.Update(dirtyManager_, parent_ ? &(parent_->GetRenderProperties()) : nullptr, dirtyFlag_);
|
||||
PrepareBaseRenderNode(node);
|
||||
@ -83,7 +91,14 @@ void RSRenderThreadVisitor::ProcessBaseRenderNode(RSBaseRenderNode& node)
|
||||
|
||||
void RSRenderThreadVisitor::ProcessRootRenderNode(RSRootRenderNode& node)
|
||||
{
|
||||
auto rsSurface = node.GetSurface();
|
||||
std::shared_ptr<RSSurface> rsSurface = nullptr;
|
||||
NodeId surfaceId = node.GetRSSurfaceNodeId();
|
||||
auto ptr = std::static_pointer_cast<RSSurfaceNode>(RSNodeMap::Instance().GetNode(surfaceId).lock());
|
||||
if (ptr == nullptr) {
|
||||
ROSEN_LOGE("No RSSurfaceNode found");
|
||||
return;
|
||||
}
|
||||
rsSurface = RSSurfaceExtractor::ExtractRSSurface(ptr);
|
||||
if (!isIdle_) {
|
||||
ProcessCanvasRenderNode(node);
|
||||
return;
|
||||
@ -139,14 +154,14 @@ void RSRenderThreadVisitor::ProcessSurfaceRenderNode(RSSurfaceRenderNode& node)
|
||||
ROSEN_LOGE("RSRenderThreadVisitor::ProcessSurfaceRenderNode, canvas is nullptr");
|
||||
return;
|
||||
}
|
||||
node.ProcessRenderBeforeChildren(*canvas_);
|
||||
// RSSurfaceRenderNode in RSRenderThreadVisitor do not have information of property.
|
||||
// We only get parent's matrix and send it to RenderService
|
||||
#ifdef ROSEN_OHOS
|
||||
node.SetMatrix(canvas_->getTotalMatrix());
|
||||
node.SetAlpha(canvas_->GetAlpha());
|
||||
node.SetParentId(node.GetParent().lock()->GetId());
|
||||
#endif
|
||||
ProcessBaseRenderNode(node);
|
||||
node.ProcessRenderAfterChildren(*canvas_);
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
|
@ -50,6 +50,7 @@ private:
|
||||
bool dirtyFlag_ = false;
|
||||
bool isIdle_ = true;
|
||||
RSPaintFilterCanvas* canvas_;
|
||||
RSRootRenderNode* curTreeRoot_ = nullptr;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -63,6 +63,12 @@ bool RSInterfaces::TakeSurfaceCapture(std::shared_ptr<RSSurfaceNode> node,
|
||||
return renderServiceClient_->TakeSurfaceCapture(node->GetId(), callback);
|
||||
}
|
||||
|
||||
bool RSInterfaces::TakeSurfaceCapture(std::shared_ptr<RSDisplayNode> node,
|
||||
std::shared_ptr<SurfaceCaptureCallback> callback)
|
||||
{
|
||||
return renderServiceClient_->TakeSurfaceCapture(node->GetId(), callback);
|
||||
}
|
||||
|
||||
void RSInterfaces::SetScreenActiveMode(ScreenId id, uint32_t modeId)
|
||||
{
|
||||
renderServiceClient_->SetScreenActiveMode(id, modeId);
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "transaction/rs_render_service_client.h"
|
||||
#include "ui/rs_display_node.h"
|
||||
#include "ui/rs_surface_node.h"
|
||||
|
||||
namespace OHOS {
|
||||
@ -46,6 +47,8 @@ public:
|
||||
|
||||
bool TakeSurfaceCapture(std::shared_ptr<RSSurfaceNode> node, std::shared_ptr<SurfaceCaptureCallback> callback);
|
||||
|
||||
bool TakeSurfaceCapture(std::shared_ptr<RSDisplayNode> node, std::shared_ptr<SurfaceCaptureCallback> callback);
|
||||
|
||||
void SetScreenActiveMode(ScreenId id, uint32_t modeId);
|
||||
|
||||
void SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status);
|
||||
|
@ -75,7 +75,6 @@ void RSBaseNode::AddChild(SharedPtr child, int index)
|
||||
children_.insert(children_.begin() + index, childId);
|
||||
}
|
||||
child->SetParent(id_);
|
||||
ROSEN_LOGD("RSBaseNode::AddChild %llu ---> %llu", id_, childId);
|
||||
child->OnAddChildren();
|
||||
std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeAddChild>(id_, childId, index);
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
@ -94,7 +93,6 @@ void RSBaseNode::RemoveChild(SharedPtr child)
|
||||
RemoveChildById(childId);
|
||||
child->OnRemoveChildren();
|
||||
child->SetParent(0);
|
||||
ROSEN_LOGD("RSBaseNode::RemoveChild %llu -/-> %llu", id_, childId);
|
||||
|
||||
std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeRemoveChild>(id_, childId);
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
|
@ -50,7 +50,6 @@ RSCanvasNode::~RSCanvasNode() {}
|
||||
SkCanvas* RSCanvasNode::BeginRecording(int width, int height)
|
||||
{
|
||||
#ifdef ROSEN_OHOS
|
||||
ROSEN_LOGD("RSCanvasNode::BeginRecording, size = [%d * %d]", width, height);
|
||||
recordingCanvas_ = new RSRecordingCanvas(width, height);
|
||||
#endif
|
||||
return recordingCanvas_;
|
||||
@ -68,7 +67,6 @@ void RSCanvasNode::FinishRecording()
|
||||
ROSEN_LOGW("RSCanvasNode::FinishRecording, IsRecording = false");
|
||||
return;
|
||||
}
|
||||
ROSEN_LOGD("RSCanvasNode::FinishRecording, node = %llu stops recording", GetId());
|
||||
auto recording = static_cast<RSRecordingCanvas*>(recordingCanvas_)->GetDrawCmdList();
|
||||
delete recordingCanvas_;
|
||||
recordingCanvas_ = nullptr;
|
||||
|
@ -221,14 +221,14 @@ bool IsValid(const Vector2f& value)
|
||||
std::make_unique<RSNodeSet##propertyName##Delta>(GetId(), value - currentValue); \
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance(); \
|
||||
if (transactionProxy != nullptr) { \
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNode()); \
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNodeForProperty()); \
|
||||
} \
|
||||
stagingProperties_.Set##propertyName(value); \
|
||||
} else { \
|
||||
std::unique_ptr<RSCommand> command = std::make_unique<RSNodeSet##propertyName>(GetId(), value); \
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance(); \
|
||||
if (transactionProxy != nullptr) { \
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNode()); \
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNodeForProperty()); \
|
||||
} \
|
||||
stagingProperties_.Set##propertyName(value); \
|
||||
}
|
||||
@ -241,7 +241,7 @@ bool IsValid(const Vector2f& value)
|
||||
std::unique_ptr<RSCommand> command = std::make_unique<RSNodeSet##propertyName>(GetId(), value); \
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance(); \
|
||||
if (transactionProxy != nullptr) { \
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNode()); \
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNodeForProperty()); \
|
||||
} \
|
||||
stagingProperties_.Set##propertyName(value);
|
||||
|
||||
@ -250,7 +250,7 @@ bool IsValid(const Vector2f& value)
|
||||
auto task = std::make_shared<RSNodeGet##propertyName>(GetId()); \
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance(); \
|
||||
if (transactionProxy != nullptr) { \
|
||||
transactionProxy->ExecuteSynchronousTask(task, IsRenderServiceNode()); \
|
||||
transactionProxy->ExecuteSynchronousTask(task, IsRenderServiceNodeForProperty()); \
|
||||
} \
|
||||
if (task->GetResult()) { \
|
||||
return task->GetValue(); \
|
||||
|
@ -234,6 +234,11 @@ protected:
|
||||
void OnRemoveChildren() override;
|
||||
void AnimationFinish(long long animationId);
|
||||
|
||||
virtual bool IsRenderServiceNodeForProperty() const
|
||||
{
|
||||
return IsRenderServiceNode();
|
||||
}
|
||||
|
||||
private:
|
||||
bool HasPropertyAnimation(const RSAnimatableProperty& property);
|
||||
void FallbackAnimationsToRoot();
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "transaction/rs_transaction_proxy.h"
|
||||
#include "ui/rs_ui_director.h"
|
||||
#include "ui/rs_surface_node.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
@ -38,14 +39,15 @@ std::shared_ptr<RSNode> RSRootNode::Create(bool isRenderServiceNode)
|
||||
|
||||
RSRootNode::RSRootNode(bool isRenderServiceNode) : RSCanvasNode(isRenderServiceNode) {}
|
||||
|
||||
void RSRootNode::AttachRSSurface(std::shared_ptr<RSSurface> surfaceProducer, int width, int height) const
|
||||
void RSRootNode::AttachRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode, int width, int height) const
|
||||
{
|
||||
std::unique_ptr<RSCommand> command =
|
||||
std::make_unique<RSRootNodeAttachRSSurface>(GetId(), surfaceProducer, width, height);
|
||||
std::make_unique<RSRootNodeAttachRSSurfaceNode>(GetId(), surfaceNode->GetId(), width, height);
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
if (transactionProxy != nullptr) {
|
||||
transactionProxy->AddCommand(command, IsRenderServiceNode());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class RSSurfaceNode;
|
||||
class RS_EXPORT RSRootNode : public RSCanvasNode {
|
||||
public:
|
||||
using WeakPtr = std::weak_ptr<RSRootNode>;
|
||||
@ -36,7 +37,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
void AttachRSSurface(std::shared_ptr<RSSurface> surfaceProducer, int width, int height) const;
|
||||
void AttachRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode, int width, int height) const;
|
||||
|
||||
RSRootNode(bool isRenderServiceNode);
|
||||
RSRootNode(const RSRootNode&) = delete;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "command/rs_surface_node_command.h"
|
||||
#include "command/rs_base_node_command.h"
|
||||
#include "pipeline/rs_node_map.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
#include "platform/drawing/rs_surface_converter.h"
|
||||
@ -101,7 +102,15 @@ RSSurfaceNode::RSSurfaceNode(const RSSurfaceNodeConfig& config, bool isRenderSer
|
||||
: RSNode(isRenderServiceNode), name_(config.SurfaceNodeName)
|
||||
{}
|
||||
|
||||
RSSurfaceNode::~RSSurfaceNode() {}
|
||||
RSSurfaceNode::~RSSurfaceNode() {
|
||||
if (!IsRenderServiceNode()) {
|
||||
std::unique_ptr<RSCommand> command = std::make_unique<RSBaseNodeDestroy>(GetId());
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
if (transactionProxy != nullptr) {
|
||||
transactionProxy->AddCommand(command, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -45,15 +45,11 @@ public:
|
||||
|
||||
bool Marshalling(Parcel& parcel) const override;
|
||||
static RSSurfaceNode* Unmarshalling(Parcel& parcel);
|
||||
#ifdef ROSEN_OHOS
|
||||
sptr<OHOS::Surface> GetSurface() const;
|
||||
#endif
|
||||
|
||||
RSUINodeType GetType() const override
|
||||
{
|
||||
return RSUINodeType::SURFACE_NODE;
|
||||
}
|
||||
|
||||
protected:
|
||||
RSSurfaceNode(bool isRenderServiceNode);
|
||||
explicit RSSurfaceNode(const RSSurfaceNodeConfig& config, bool isRenderServiceNode);
|
||||
@ -61,6 +57,10 @@ protected:
|
||||
RSSurfaceNode(const RSSurfaceNode&&) = delete;
|
||||
RSSurfaceNode& operator=(const RSSurfaceNode&) = delete;
|
||||
RSSurfaceNode& operator=(const RSSurfaceNode&&) = delete;
|
||||
bool IsRenderServiceNodeForProperty() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
bool CreateNodeAndSurface(const RSSurfaceRenderNodeConfig& config);
|
||||
|
@ -62,6 +62,10 @@ void RSUIDirector::Destory()
|
||||
void RSUIDirector::SetRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode)
|
||||
{
|
||||
surfaceNode_ = surfaceNode;
|
||||
if (surfaceNode == nullptr) {
|
||||
ROSEN_LOGE("RSUIDirector::SetRSSurfaceNode, no surfaceNode is ready to be set");
|
||||
return;
|
||||
}
|
||||
if (root_ == 0) {
|
||||
ROSEN_LOGE("RSUIDirector::SetRSSurfaceNode, no root exists");
|
||||
return;
|
||||
@ -71,12 +75,7 @@ void RSUIDirector::SetRSSurfaceNode(std::shared_ptr<RSSurfaceNode> surfaceNode)
|
||||
ROSEN_LOGE("RSUIDirector::SetRSSurfaceNode, get root node failed");
|
||||
return;
|
||||
}
|
||||
if (surfaceNode == nullptr) {
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurface(0, 0, 0);
|
||||
} else {
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurface(
|
||||
RSSurfaceExtractor::ExtractRSSurface(surfaceNode_), surfaceWidth_, surfaceHeight_);
|
||||
}
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurfaceNode(surfaceNode_, surfaceWidth_, surfaceHeight_);
|
||||
}
|
||||
|
||||
void RSUIDirector::SetSurfaceNodeSize(int width, int height)
|
||||
@ -89,8 +88,7 @@ void RSUIDirector::SetSurfaceNodeSize(int width, int height)
|
||||
}
|
||||
auto node = RSNodeMap::Instance().GetNode(root_).lock();
|
||||
if (node != nullptr) {
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurface(
|
||||
RSSurfaceExtractor::ExtractRSSurface(surfaceNode_), surfaceWidth_, surfaceHeight_);
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurfaceNode(surfaceNode_, surfaceWidth_, surfaceHeight_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,8 +109,7 @@ void RSUIDirector::SetRoot(NodeId root)
|
||||
return;
|
||||
}
|
||||
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurface(
|
||||
RSSurfaceExtractor::ExtractRSSurface(surfaceNode_), surfaceWidth_, surfaceHeight_);
|
||||
std::static_pointer_cast<RSRootNode>(node)->AttachRSSurfaceNode(surfaceNode_, surfaceWidth_, surfaceHeight_);
|
||||
}
|
||||
|
||||
void RSUIDirector::SetTimeStamp(uint64_t timeStamp)
|
||||
|
@ -14,6 +14,5 @@
|
||||
declare_args() {
|
||||
use_flutter_texture = false
|
||||
enable_export_macro = true
|
||||
enable_debug = true
|
||||
rosen_root = "//foundation/graphic/standard/rosen"
|
||||
}
|
||||
|
@ -97,3 +97,41 @@ ohos_executable("virtual_display_demo") {
|
||||
part_name = "graphic_standard"
|
||||
subsystem_name = "graphic"
|
||||
}
|
||||
|
||||
ohos_executable("render_service_client_surface_node_demo") {
|
||||
sources = [ "render_service_client_surface_node_demo.cpp" ]
|
||||
|
||||
include_dirs = [
|
||||
"//foundation/windowmanager/interfaces/innerkits",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_client",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics/include",
|
||||
"//foundation/multimedia/media_standard/interfaces/innerkits/native/media/include",
|
||||
"//foundation/multimedia/media_standard/services/utils/include",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
|
||||
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
|
||||
"//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base",
|
||||
"//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client",
|
||||
"//foundation/multimedia/image_standard/interfaces/innerkits:image_native",
|
||||
"//foundation/windowmanager/adapter:libwmadapter",
|
||||
"//foundation/windowmanager/wm:libwm",
|
||||
"//foundation/windowmanager/wm:libwmutil",
|
||||
"//foundation/windowmanager/wmserver:libwms",
|
||||
"//third_party/zlib:libz",
|
||||
"//utils/native/base:utils",
|
||||
]
|
||||
|
||||
public_deps = [ "//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos" ]
|
||||
|
||||
external_deps = [
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"ipc:ipc_core",
|
||||
"multimedia_media_standard:media_client",
|
||||
]
|
||||
|
||||
part_name = "graphic_standard"
|
||||
subsystem_name = "graphic"
|
||||
}
|
||||
|
84
rosen/modules/render_service_client/test/media_callback.h
Normal file
84
rosen/modules/render_service_client/test/media_callback.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "foundation/multimedia/media_standard/interfaces/innerkits/native/media/include/player.h"
|
||||
#include "platform/common/rs_log.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MILLISECONDS_TO_SECONDS = 1000;
|
||||
|
||||
} // namespace
|
||||
|
||||
const std::map<OHOS::Media::PlayerStates, std::string> STATE_MAP = {
|
||||
{OHOS::Media::PlayerStates::PLAYER_STATE_ERROR, "Error"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_IDLE, "Idle"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_INITIALIZED, "Initialized"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_PREPARED, "Prepared"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_STARTED, "Started"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_PAUSED, "Paused"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_STOPPED, "Stopped"},
|
||||
{OHOS::Media::PlayerStates::PLAYER_PLAYBACK_COMPLETE, "Complete"},
|
||||
};
|
||||
|
||||
struct MediaCallback : public OHOS::Media::PlayerCallback {
|
||||
|
||||
public:
|
||||
MediaCallback() = default;
|
||||
~MediaCallback() = default;
|
||||
|
||||
void OnError(OHOS::Media::PlayerErrorType errorType, int32_t errorCode) override
|
||||
{
|
||||
std::cout << "OnError callback, errorType: "<< errorType << "errorCode: " << errorCode << std::endl;
|
||||
}
|
||||
|
||||
virtual void OnInfo(OHOS::Media::PlayerOnInfoType type, int32_t extra, const OHOS::Media::Format &InfoBody = {}) override
|
||||
{
|
||||
switch (type) {
|
||||
case OHOS::Media::INFO_TYPE_SEEKDONE:
|
||||
std::cout << "PlayerCallback: OnSeekDone currentPositon is " << extra << std::endl;
|
||||
break;
|
||||
case OHOS::Media::INFO_TYPE_EOS:
|
||||
std::cout << "PlayerCallback: OnEndOfStream isLooping is " << extra << std::endl;
|
||||
break;
|
||||
case OHOS::Media::INFO_TYPE_STATE_CHANGE:
|
||||
state_ = static_cast<OHOS::Media::PlayerStates>(extra);
|
||||
PrintState(state_);
|
||||
break;
|
||||
case OHOS::Media::INFO_TYPE_POSITION_UPDATE:
|
||||
// std::cout << "OnPositionUpdated positon is " << extra << std::endl;
|
||||
break;
|
||||
case OHOS::Media::INFO_TYPE_MESSAGE:
|
||||
std::cout << "PlayerCallback: OnMessage is " << extra << std::endl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void PrintState(OHOS::Media::PlayerStates state) const
|
||||
{
|
||||
if (STATE_MAP.count(state) != 0) {
|
||||
std::cout << "State:" << (STATE_MAP.at(state)).c_str() << std::endl;
|
||||
} else {
|
||||
std::cout << "Invalid state" << std::endl;
|
||||
}
|
||||
}
|
||||
Media::PlayerStates state_ = Media::PLAYER_STATE_ERROR;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
@ -0,0 +1,184 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <surface.h>
|
||||
#include <cinttypes>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <securec.h>
|
||||
#include <sstream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "display_type.h"
|
||||
#include "wm/window.h"
|
||||
|
||||
#include "include/core/SkCanvas.h"
|
||||
#include "include/core/SkImageInfo.h"
|
||||
#include "transaction/rs_transaction.h"
|
||||
#include "ui/rs_root_node.h"
|
||||
#include "ui/rs_display_node.h"
|
||||
#include "ui/rs_surface_node.h"
|
||||
#include "ui/rs_surface_extractor.h"
|
||||
#include "ui/rs_ui_director.h"
|
||||
#include "image/bitmap.h"
|
||||
#include "draw/canvas.h"
|
||||
#include "draw/color.h"
|
||||
|
||||
#include "media_callback.h"
|
||||
|
||||
#include "player.h"
|
||||
#include "nocopyable.h"
|
||||
#include "media_data_source.h"
|
||||
|
||||
const char* SURFACE_STRIDE_ALIGNMENT = "8";
|
||||
constexpr int32_t SURFACE_QUEUE_SIZE = 5;
|
||||
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::Rosen;
|
||||
using namespace OHOS::Rosen::Drawing;
|
||||
using namespace std;
|
||||
|
||||
std::map<std::string, std::function<int32_t()>> playerTable;
|
||||
|
||||
void RegisterTable(std::shared_ptr<OHOS::Media::Player> player)
|
||||
{
|
||||
(void)playerTable.emplace("prepare", std::bind(&OHOS::Media::Player::Prepare, player));
|
||||
(void)playerTable.emplace("prepareasync", std::bind(&OHOS::Media::Player::PrepareAsync, player));
|
||||
(void)playerTable.emplace("", std::bind(&OHOS::Media::Player::Play, player)); // ENTER -> play
|
||||
(void)playerTable.emplace("play", std::bind(&OHOS::Media::Player::Play, player));
|
||||
(void)playerTable.emplace("pause", std::bind(&OHOS::Media::Player::Pause, player));
|
||||
(void)playerTable.emplace("stop", std::bind(&OHOS::Media::Player::Stop, player));
|
||||
(void)playerTable.emplace("reset", std::bind(&OHOS::Media::Player::Reset, player));
|
||||
(void)playerTable.emplace("release", std::bind(&OHOS::Media::Player::Release, player));
|
||||
}
|
||||
|
||||
void DoNext()
|
||||
{
|
||||
cout << "Enter your step:" << endl;
|
||||
std::string cmd;
|
||||
while (std::getline(std::cin, cmd)) {
|
||||
auto iter = playerTable.find(cmd);
|
||||
if (iter != playerTable.end()) {
|
||||
auto func = iter->second;
|
||||
if (func() != 0) {
|
||||
cout << "Operation error" << endl;
|
||||
}
|
||||
continue;
|
||||
} else if (cmd.find("quit") != std::string::npos || cmd == "q") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Init(std::shared_ptr<RSUIDirector> rsUiDirector, int width, int height)
|
||||
{
|
||||
std::cout << "rs app demo Init Rosen Backend!" << std::endl;
|
||||
|
||||
if (!rsUiDirector) {
|
||||
return;
|
||||
}
|
||||
rsUiDirector->SetSurfaceNodeSize(width, height);
|
||||
rsUiDirector->Init();
|
||||
std::cout << "Init Rosen Backend" << std::endl;
|
||||
|
||||
auto rootNode = RSRootNode::Create();
|
||||
cout << "RootNode id = " << rootNode->GetId() << endl;
|
||||
rootNode->SetFrame(0, 0, width, height);
|
||||
rootNode->SetBackgroundColor(SK_ColorWHITE);
|
||||
rsUiDirector->SetRoot(rootNode->GetId());
|
||||
|
||||
auto canvasNode = RSCanvasNode::Create();
|
||||
cout << "canvasNode id = " << canvasNode->GetId() << endl;
|
||||
canvasNode->SetFrame(100, 100, 960, 1000);
|
||||
canvasNode->SetBackgroundColor(SK_ColorRED);
|
||||
rootNode->AddChild(canvasNode, -1);
|
||||
|
||||
struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
|
||||
auto surfaceNode = RSSurfaceNode::Create(rsSurfaceNodeConfig, false);
|
||||
cout << "surfaceNode id = " << surfaceNode->GetId() << endl;
|
||||
surfaceNode->SetBounds(300, 300, 960, 540);
|
||||
|
||||
canvasNode->AddChild(surfaceNode, -1);
|
||||
rsUiDirector->SendMessages();
|
||||
auto player = OHOS::Media::PlayerFactory::CreatePlayer();
|
||||
if (player == nullptr) {
|
||||
cout << "player is null" << endl;
|
||||
return;
|
||||
}
|
||||
RegisterTable(player);
|
||||
std::shared_ptr<OHOS::Ace::MediaCallback> cb = std::make_shared<OHOS::Ace::MediaCallback>();
|
||||
int32_t media_ret = -1;
|
||||
media_ret = player->SetPlayerCallback(cb);
|
||||
if (media_ret != 0) {
|
||||
cout << "SetPlayerCallback fail" << endl;
|
||||
}
|
||||
// Use Local file source here
|
||||
// path is /data/H264_Main.mp4
|
||||
media_ret = player->SetSource("/data/H264_Main.mp4");
|
||||
if (media_ret != 0) {
|
||||
cout << "SetSource fail" << endl;
|
||||
return;
|
||||
}
|
||||
sptr<Surface> producerSurface = nullptr;
|
||||
producerSurface = surfaceNode->GetSurface();
|
||||
producerSurface->SetQueueSize(SURFACE_QUEUE_SIZE);
|
||||
producerSurface->SetUserData("SURFACE_STRIDE_ALIGNMENT", SURFACE_STRIDE_ALIGNMENT);
|
||||
producerSurface->SetUserData("SURFACE_FORMAT", std::to_string(PIXEL_FMT_RGBA_8888));
|
||||
if (producerSurface != nullptr) {
|
||||
media_ret = player->SetVideoSurface(producerSurface);
|
||||
if (media_ret != 0) {
|
||||
cout << "SetVideoSurface fail" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
media_ret = player->PrepareAsync();
|
||||
if (media_ret != 0) {
|
||||
cout << "PrepareAsync fail" << endl;
|
||||
return;
|
||||
}
|
||||
DoNext();
|
||||
sleep(10);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "rs app demo start!" << std::endl;
|
||||
sptr<WindowOption> option = new WindowOption();
|
||||
option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
|
||||
option->SetWindowRect({200, 200, 1501, 1200});
|
||||
auto window = Window::Create("app_demo", option);
|
||||
|
||||
window->Show();
|
||||
auto rect = window->GetRect();
|
||||
std::cout << "rs app demo create window " << rect.width_ << " " << rect.height_ << std::endl;
|
||||
auto windowSurfaceNode = window->GetSurfaceNode();
|
||||
cout << "windowSurfaceNode id = " << windowSurfaceNode->GetId() << endl;
|
||||
|
||||
auto rsUiDirector = RSUIDirector::Create();
|
||||
rsUiDirector->Init();
|
||||
RSTransaction::FlushImplicitTransaction();
|
||||
sleep(1);
|
||||
|
||||
rsUiDirector->SetRSSurfaceNode(windowSurfaceNode);
|
||||
Init(rsUiDirector, rect.width_, rect.height_);
|
||||
std::cout << "rs app demo end!" << std::endl;
|
||||
window->Hide();
|
||||
window->Destroy();
|
||||
return 0;
|
||||
}
|
@ -79,11 +79,17 @@ void DrawSurfaceToCapture(std::shared_ptr<RSSurfaceNode> surfaceNode)
|
||||
surfaceNode->SetBounds(x, y, width, height);
|
||||
std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
|
||||
if (rsSurface == nullptr) {
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** DrawSurfaceToCapture: rsSurface == nullptr");
|
||||
return;
|
||||
}
|
||||
auto frame = rsSurface->RequestFrame(width, height);
|
||||
framePtr = std::move(frame);
|
||||
|
||||
auto canvas = framePtr->GetCanvas();
|
||||
if (canvas == nullptr) {
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** DrawSurfaceToCapture: canvas == nullptr");
|
||||
return;
|
||||
}
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
@ -98,7 +104,6 @@ void DrawSurfaceToCapture(std::shared_ptr<RSSurfaceNode> surfaceNode)
|
||||
pathPaint.setStrokeWidth(5);
|
||||
pathPaint.setStrokeJoin(SkPaint::kRound_Join);
|
||||
pathPaint.setColor(0xffFFD700);
|
||||
|
||||
canvas->drawRect(shapeGeometry, paint);
|
||||
canvas->drawPath(path, pathPaint);
|
||||
framePtr->SetDamageRegion(0, 0, width, height);
|
||||
@ -110,29 +115,33 @@ void DrawPixelmap(std::shared_ptr<RSSurfaceNode> surfaceNode, std::shared_ptr<Me
|
||||
{
|
||||
std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
|
||||
if (rsSurface == nullptr) {
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : rsSurface == nullptr\n");
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : rsSurface == nullptr");
|
||||
return;
|
||||
}
|
||||
if (pixelmap == nullptr) {
|
||||
return;
|
||||
}
|
||||
int width = pixelmap->GetWidth();
|
||||
int height = pixelmap->GetHeight();
|
||||
int sWidth = surfaceNode->GetStagingProperties().GetBoundsWidth();
|
||||
int sHeight = surfaceNode->GetStagingProperties().GetBoundsHeight();
|
||||
ROSEN_LOGD("SurfaceCaptureTest: DrawPxielmap [%u][%u][%u][%u]", width, height, sWidth, sHeight);
|
||||
auto frame = rsSurface->RequestFrame(sWidth, sHeight);
|
||||
if (frame == nullptr) {
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : frame == nullptr\n");
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : frame == nullptr");
|
||||
return;
|
||||
}
|
||||
framePtr = std::move(frame);
|
||||
auto canvas = framePtr->GetCanvas();
|
||||
if (canvas == nullptr) {
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : canvas == nullptr\n");
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : canvas == nullptr");
|
||||
return;
|
||||
}
|
||||
canvas->drawColor(0xFF87CEEB);
|
||||
SkImageInfo layerInfo = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||
auto addr = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
|
||||
if (addr == nullptr) {
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : addr == nullptr\n");
|
||||
ROSEN_LOGE("***SurfaceCaptureTest*** : addr == nullptr");
|
||||
return;
|
||||
}
|
||||
SkPixmap pixmap(layerInfo, addr, pixelmap->GetRowBytes());
|
||||
@ -240,13 +249,15 @@ int main()
|
||||
{
|
||||
DisplayId id = g_dms.GetDefaultDisplayId();
|
||||
cout << "RS default screen id is " << id << ".\n";
|
||||
ROSEN_LOGD("***SurfaceCaptureTest*** main: begin\n");
|
||||
ROSEN_LOGD("***SurfaceCaptureTest*** main: begin");
|
||||
|
||||
auto surfaceLauncher = CreateSurface();
|
||||
auto surfaceNode1 = CreateSurface();
|
||||
auto surfaceNode2 = CreateSurface();
|
||||
DrawSurface(SkRect::MakeXYWH(0, 0, 2800, 1600), 0xFFF0FFF0, SkRect::MakeXYWH(0, 0, 2800, 1600), surfaceLauncher);
|
||||
auto surfaceNode3 = CreateSurface();
|
||||
DrawSurface(SkRect::MakeXYWH(0, 0, 1400, 1200), 0xFFF0FFF0, SkRect::MakeXYWH(0, 0, 1400, 1200), surfaceLauncher);
|
||||
DrawSurface(SkRect::MakeXYWH(500, 100, 512, 512), 0xFF8B008B, SkRect::MakeXYWH(20, 20, 230, 230), surfaceNode1);
|
||||
DrawSurface(SkRect::MakeXYWH(1700, 100, 512, 512), 0xFF00FF40, SkRect::MakeXYWH(20, 20, 230, 230), surfaceNode3);
|
||||
DrawSurfaceToCapture(surfaceNode2);
|
||||
RSDisplayNodeConfig config;
|
||||
config.screenId = id;
|
||||
@ -254,10 +265,8 @@ int main()
|
||||
displayNode->AddChild(surfaceLauncher, -1);
|
||||
displayNode->AddChild(surfaceNode1, -1);
|
||||
displayNode->AddChild(surfaceNode2, -1);
|
||||
auto transactionProxy = RSTransactionProxy::GetInstance();
|
||||
if (transactionProxy != nullptr) {
|
||||
transactionProxy->FlushImplicitTransaction();
|
||||
}
|
||||
displayNode->AddChild(surfaceNode3, -1);
|
||||
RSTransactionProxy::GetInstance().FlushImplicitTransaction();
|
||||
|
||||
class TestSurfaceCapture : public SurfaceCaptureCallback {
|
||||
public:
|
||||
@ -273,6 +282,9 @@ int main()
|
||||
sleep(2);
|
||||
std::shared_ptr<SurfaceCaptureCallback> cb = make_shared<TestSurfaceCapture>(surfaceNode1);
|
||||
g_dms.rsInterface_.TakeSurfaceCapture(surfaceNode2, cb);
|
||||
ROSEN_LOGD("***SurfaceCaptureTest*** main: end\n");
|
||||
sleep(2);
|
||||
std::shared_ptr<SurfaceCaptureCallback> cb2 = make_shared<TestSurfaceCapture>(surfaceNode3);
|
||||
g_dms.rsInterface_.TakeSurfaceCapture(displayNode, cb2);
|
||||
ROSEN_LOGD("***SurfaceCaptureTest*** main: end");
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user