1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <iostream>
17 #include <surface.h>
18 #include "SkColor.h"
19 #include "foundation/window/window_manager/interfaces/innerkits/dm/display_manager.h"
20
21 #include "transaction/rs_transaction.h"
22 #include "ui/rs_display_node.h"
23 #include "ui/rs_surface_node.h"
24
25 using namespace OHOS;
26 using namespace OHOS::Rosen;
27
28 namespace {
29 constexpr uint32_t SLEEP_TIME = 1;
30 constexpr uint32_t RETURN_WAIT_TIME = 1000;
31 constexpr float NODE_BOUND_LEFT = 500;
32 constexpr float NODE_BOUND_TOP = 500;
33 constexpr float NODE_BOUND_WIDTH = 1000;
34 constexpr float NODE_BOUND_HEIGHT = 1500;
35 constexpr int32_t BUFFER_WIDTH = 1440;
36 constexpr int32_t BUFFER_HEIGHT = 1080;
37 constexpr float START_POINT_POSITION = 10;
38 constexpr float END_POINT_POSITION = 100;
39 constexpr Drawing::scalar PEN_WIDTH = 10;
40 }
41 std::shared_ptr<RSSurfaceNode> surfaceNode;
42 uint64_t screenId = 0;
43
44
GetSurfaceBuffer(sptr<Surface> ohosSurface,int32_t width,int32_t height)45 sptr<SurfaceBuffer> GetSurfaceBuffer(sptr<Surface> ohosSurface, int32_t width, int32_t height)
46 {
47 sptr<SurfaceBuffer> buffer;
48 int32_t releaseFence = 0;
49 BufferRequestConfig config = {
50 .width = width,
51 .height = height,
52 .strideAlignment = 0x8,
53 .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
54 .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
55 };
56
57 SurfaceError ret = ohosSurface->RequestBuffer(buffer, releaseFence, config);
58 if (ret != SURFACE_ERROR_OK) {
59 return nullptr;
60 }
61 return buffer;
62 }
63
DoDraw(uint8_t * addr,uint32_t width,uint32_t height)64 void DoDraw(uint8_t* addr, uint32_t width, uint32_t height)
65 {
66 Drawing::Bitmap bitmap;
67 Drawing::BitmapFormat format { Drawing::COLORTYPE_RGBA_8888, Drawing::ALPHATYPE_OPAQUE };
68 bitmap.Build(width, height, format);
69
70 Drawing::Canvas canvas;
71 canvas.Bind(bitmap);
72 canvas.Clear(Drawing::Color::COLOR_RED);
73 Drawing::Pen pen;
74 pen.SetAntiAlias(true);
75 pen.SetColor(Drawing::Color::COLOR_GREEN);
76 Drawing::scalar penWidth = PEN_WIDTH;
77 pen.SetWidth(penWidth);
78 canvas.AttachPen(pen);
79 Drawing::Point startPt(START_POINT_POSITION, START_POINT_POSITION);
80 Drawing::Point endPt(END_POINT_POSITION, END_POINT_POSITION);
81 canvas.DrawLine(startPt, endPt);
82 static constexpr uint32_t stride = 4;
83 uint32_t addrSize = width * height * stride;
84 memcpy_s(addr, addrSize, bitmap.GetPixels(), addrSize);
85 }
86
InitSurfaceStyle(std::shared_ptr<RSSurfaceNode> surfaceNode)87 void InitSurfaceStyle(std::shared_ptr<RSSurfaceNode> surfaceNode)
88 {
89 auto ohosSurface = surfaceNode->GetSurface();
90 if (ohosSurface == nullptr) {
91 return;
92 }
93 ohosSurface->SetTransform(GraphicTransformType::GRAPHIC_ROTATE_270);
94 sptr<SurfaceBuffer> buffer = GetSurfaceBuffer(ohosSurface, BUFFER_WIDTH, BUFFER_HEIGHT);
95 if (buffer == nullptr || buffer->GetVirAddr() == nullptr) {
96 return;
97 }
98 auto addr = static_cast<uint8_t*>(buffer->GetVirAddr());
99 DoDraw(addr, buffer->GetWidth(), buffer->GetHeight());
100 BufferFlushConfig flushConfig = {
101 .damage = {
102 .w = buffer->GetWidth(),
103 .h = buffer->GetHeight(),
104 }
105 };
106 ohosSurface->FlushBuffer(buffer, -1, flushConfig);
107 }
108
InitSurface()109 bool InitSurface()
110 {
111 std::cout << "InitSurface" << std::endl;
112 DisplayId displayId = DisplayManager::GetInstance().GetDefaultDisplayId();
113 RSSurfaceNodeConfig surfaceNodeConfig;
114 surfaceNodeConfig.SurfaceNodeName = "test window";
115 RSSurfaceNodeType surfaceNodeType = RSSurfaceNodeType::APP_WINDOW_NODE;
116 std::cout << "RSSurfaceNode::Create" << std::endl;
117 surfaceNode = RSSurfaceNode::Create(surfaceNodeConfig, surfaceNodeType);
118 if (!surfaceNode) {
119 return false;
120 }
121
122 surfaceNode->SetPositionZ(RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
123 surfaceNode->SetBounds(NODE_BOUND_LEFT, NODE_BOUND_TOP, NODE_BOUND_WIDTH, NODE_BOUND_HEIGHT);
124 surfaceNode->SetBackgroundColor(SK_ColorBLACK);
125
126 std::cout << "GetDisplayById: " << std::endl;
127 screenId = DisplayManager::GetInstance().GetDisplayById(displayId)->GetId();
128 std::cout << "ScreenId: " << screenId << std::endl;
129 surfaceNode->AttachToDisplay(screenId);
130
131 std::cout << "RSTranscation::FlushImplicitTransaction" << std::endl;
132 RSTransaction::FlushImplicitTransaction();
133 sleep(SLEEP_TIME);
134 return true;
135 }
136
main()137 int main()
138 {
139 std::cout << "rs fix rotation demo start!" << std::endl;
140 InitSurface();
141
142 Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = "test",
143 .isTextureExportNode = false };
144 auto hardwareNode = RSSurfaceNode::Create(surfaceNodeConfig, false);
145 hardwareNode->SetHardwareEnabled(true);
146 hardwareNode->SetBounds(0, 0, NODE_BOUND_WIDTH, NODE_BOUND_HEIGHT);
147 hardwareNode->SetBackgroundColor(SK_ColorGREEN);
148
149 surfaceNode->AddChild(hardwareNode, -1);
150 RSTransaction::FlushImplicitTransaction();
151 sleep(1);
152
153 InitSurfaceStyle(hardwareNode);
154 RSTransaction::FlushImplicitTransaction();
155 sleep(SLEEP_TIME);
156 hardwareNode->SetForceHardwareAndFixRotation(true);
157 RSTransaction::FlushImplicitTransaction();
158
159 sleep(RETURN_WAIT_TIME);
160 return 0;
161 }