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 }