!175 更新renderservice代码

Merge pull request !175 from lijj01/master
This commit is contained in:
openharmony_ci 2022-01-12 07:05:06 +00:00 committed by Gitee
commit d3e787aa16
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
56 changed files with 1233 additions and 567 deletions

View File

@ -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"

View File

@ -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
}
}
}

View File

@ -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

View File

@ -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);

View File

@ -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",

View File

@ -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()

View File

@ -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);

View File

@ -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_;

View File

@ -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();

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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" ]
}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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;

View File

@ -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:

View File

@ -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);
}
}

View File

@ -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

View File

@ -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_) {

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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());

View File

@ -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",
]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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") {

View File

@ -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_);

View File

@ -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

View File

@ -50,6 +50,7 @@ private:
bool dirtyFlag_ = false;
bool isIdle_ = true;
RSPaintFilterCanvas* canvas_;
RSRootRenderNode* curTreeRoot_ = nullptr;
};
} // namespace Rosen
} // namespace OHOS

View File

@ -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);

View File

@ -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);

View File

@ -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();

View File

@ -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;

View File

@ -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(); \

View File

@ -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();

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -14,6 +14,5 @@
declare_args() {
use_flutter_texture = false
enable_export_macro = true
enable_debug = true
rosen_root = "//foundation/graphic/standard/rosen"
}

View File

@ -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"
}

View 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

View File

@ -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;
}

View File

@ -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;
}