• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 
19 #include "command/rs_base_node_command.h"
20 #include "command/rs_display_node_command.h"
21 #include "command/rs_surface_node_command.h"
22 #include "common/rs_common_def.h"
23 
24 #include "pipeline/rs_render_result.h"
25 #include "platform/common/rs_log.h"
26 #include "ui/rs_node.h"
27 #include "ui/rs_surface_extractor.h"
28 #include "ui/rs_ui_director.h"
29 #include "transaction/rs_interfaces.h"
30 #include "ui/rs_display_node.h"
31 #include "ui/rs_surface_node.h"
32 #include "pixel_map.h"
33 
34 using namespace OHOS;
35 using namespace OHOS::Rosen;
36 using namespace std;
37 
38 std::unique_ptr<RSSurfaceFrame> framePtr;
39 
DrawSurface(Drawing::Rect surfaceGeometry,uint32_t color,Drawing::Rect shapeGeometry,std::shared_ptr<RSSurfaceNode> surfaceNode)40 void DrawSurface(Drawing::Rect surfaceGeometry,
41     uint32_t color, Drawing::Rect shapeGeometry, std::shared_ptr<RSSurfaceNode> surfaceNode)
42 {
43     auto x = surfaceGeometry.GetLeft();
44     auto y = surfaceGeometry.GetTop();
45     auto width = surfaceGeometry.GetWidth();
46     auto height = surfaceGeometry.GetHeight();
47     surfaceNode->SetBounds(x, y, width, height);
48     std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
49     if (rsSurface == nullptr) {
50         return;
51     }
52     auto frame = rsSurface->RequestFrame(width, height);
53     framePtr = std::move(frame);
54     auto canvas = framePtr->GetCanvas();
55 
56     Drawing::Brush brush;
57     brush.SetAntiAlias(true);
58     brush.SetColor(color);
59 
60     canvas->AttachBrush(brush);
61     canvas->DrawRect(shapeGeometry);
62     canvas->DetachBrush();
63     framePtr->SetDamageRegion(0, 0, width, height);
64     auto framePtr1 = std::move(framePtr);
65     rsSurface->FlushFrame(framePtr1);
66 }
67 
DrawSurfaceToCapture(std::shared_ptr<RSSurfaceNode> surfaceNode)68 void DrawSurfaceToCapture(std::shared_ptr<RSSurfaceNode> surfaceNode)
69 {
70     Drawing::Rect surfaceGeometry = Drawing::Rect(50, 50, 178, 178);
71     Drawing::Rect shapeGeometry = Drawing::Rect(10, 20, 50, 68);
72     auto x = surfaceGeometry.GetLeft();
73     auto y = surfaceGeometry.GetTop();
74     auto width = surfaceGeometry.GetWidth();
75     auto height = surfaceGeometry.GetHeight();
76     surfaceNode->SetBounds(x, y, width, height);
77     std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
78     if (rsSurface == nullptr) {
79         ROSEN_LOGE("***SurfaceCaptureTest*** DrawSurfaceToCapture: rsSurface == nullptr");
80         return;
81     }
82     auto frame = rsSurface->RequestFrame(width, height);
83     framePtr = std::move(frame);
84 
85     auto canvas = framePtr->GetCanvas();
86     if (canvas == nullptr) {
87         ROSEN_LOGE("***SurfaceCaptureTest*** DrawSurfaceToCapture: canvas == nullptr");
88         return;
89     }
90     Drawing::Brush brush;
91     brush.SetAntiAlias(true);
92     brush.SetColor(0xffff0000);
93     canvas->AttachBrush(brush);
94     canvas->drawRect(shapeGeometry);
95     canvas->DetachBrush();
96 
97     Drawing::Path path;
98     path.CubicTo(10, 10, 25, 80, 60, 80);
99     Drawing::Brush pathBrush;
100     pathBrush.SetAntiAlias(true);
101     pathBrush.SetColor(0xffFFD700);
102     canvas->AttachBrush(pathBrush);
103     canvas->drawPath(path);
104     canvas->DetachBrush();
105     framePtr->SetDamageRegion(0, 0, width, height);
106     auto framePtr1 = std::move(framePtr);
107     rsSurface->FlushFrame(framePtr1);
108 }
109 
DrawPixelmap(std::shared_ptr<RSSurfaceNode> surfaceNode,std::shared_ptr<Media::PixelMap> pixelmap)110 void DrawPixelmap(std::shared_ptr<RSSurfaceNode> surfaceNode, std::shared_ptr<Media::PixelMap> pixelmap)
111 {
112     std::shared_ptr<RSSurface> rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode);
113     if (rsSurface == nullptr) {
114         ROSEN_LOGE("***SurfaceCaptureTest*** : rsSurface == nullptr");
115         return;
116     }
117     if (pixelmap == nullptr) {
118         return;
119     }
120     int width = pixelmap->GetWidth();
121     int height = pixelmap->GetHeight();
122     int sWidth = surfaceNode->GetStagingProperties().GetBoundsWidth();
123     int sHeight = surfaceNode->GetStagingProperties().GetBoundsHeight();
124     ROSEN_LOGD("SurfaceCaptureTest: DrawPxielmap [%{public}u][%{public}u][%{public}u][%{public}u]",
125         width, height, sWidth, sHeight);
126     auto frame = rsSurface->RequestFrame(sWidth, sHeight);
127     if (frame == nullptr) {
128         ROSEN_LOGE("***SurfaceCaptureTest*** : frame == nullptr");
129         return;
130     }
131     framePtr = std::move(frame);
132     auto canvas = framePtr->GetCanvas();
133     if (canvas == nullptr) {
134         ROSEN_LOGE("***SurfaceCaptureTest*** : canvas == nullptr");
135         return;
136     }
137     canvas->DrawColor(0xFF87CEEB);
138     Drawing::Bitmap bitmap;
139     bitmap.Build(width, height, Drawing::BitmapFormat{
140         Drawing::ColorType::COLORTYPE_RGBA_8888, Drawing::AlphaType::ALPHATYPE_PREMUL});
141     auto addr = const_cast<uint32_t*>(pixelmap->GetPixel32(0, 0));
142     if (addr == nullptr) {
143         ROSEN_LOGE("***SurfaceCaptureTest*** : addr == nullptr");
144         return;
145     }
146     bitmap.SetPixels(addr);
147 
148     Drawing::Image image;
149     image.BuildFromBitmap(bitmap);
150     canvas->DrawImageRect(image, Drawing::Rect(0, 0, sWidth, sHeight), nullptr);
151     framePtr->SetDamageRegion(0, 0, sWidth, sHeight);
152     auto framePtr1 = std::move(framePtr);
153     rsSurface->FlushFrame(framePtr1);
154 }
155 
156 
CreateSurface()157 std::shared_ptr<RSSurfaceNode> CreateSurface()
158 {
159     RSSurfaceNodeConfig config;
160     config.SurfaceNodeName = "ThisIsSurfaceCaptureName";
161     return RSSurfaceNode::Create(config);
162 }
163 
164 // Toy DMS.
165 using DisplayId = ScreenId;
166 class MyDMS {
167 public:
MyDMS()168     MyDMS() : rsInterface_(RSInterfaces::GetInstance())
169     {
170         Init();
171     }
172     ~MyDMS() noexcept = default;
173     RSInterfaces& rsInterface_;
174 
GetDefaultDisplayId() const175     DisplayId GetDefaultDisplayId() const
176     {
177         std::lock_guard<std::recursive_mutex> lock(mutex_);
178         return defaultDisplayId_;
179     }
180 
GetDisplayActiveMode(DisplayId id) const181     std::optional<RSScreenModeInfo> GetDisplayActiveMode(DisplayId id) const
182     {
183         std::lock_guard<std::recursive_mutex> lock(mutex_);
184         if (displays_.count(id) == 0) {
185             cout << "MyDMS: No display " << id << "!" << endl;
186             return {};
187         }
188         return displays_.at(id).activeMode;
189     }
190 
OnDisplayConnected(ScreenId id)191     void OnDisplayConnected(ScreenId id)
192     {
193         std::lock_guard<std::recursive_mutex> lock(mutex_);
194         displays_[id] = Display { id, rsInterface_.GetScreenActiveMode(id) };
195         std::cout << "MyDMS: Display " << id << " connected." << endl;
196     }
197 
OnDisplayDisConnected(ScreenId id)198     void OnDisplayDisConnected(ScreenId id)
199     {
200         std::lock_guard<std::recursive_mutex> lock(mutex_);
201         if (displays_.count(id) == 0) {
202             cout << "MyDMS: No display " << id << "!" << endl;
203         } else {
204             std::cout << "MyDMS: Display " << id << " disconnected." << endl;
205             displays_.erase(id);
206             if (id == defaultDisplayId_) {
207                 defaultDisplayId_ = rsInterface_.GetDefaultScreenId();
208                 std::cout << "MyDMS: DefaultDisplayId changed, new DefaultDisplayId is" << defaultDisplayId_ << "."
209                           << endl;
210             }
211         }
212     }
213 
214     private:
215     struct Display {
216         DisplayId id;
217         RSScreenModeInfo activeMode;
218     };
219     std::unordered_map<DisplayId, Display> displays_;
220     mutable std::recursive_mutex mutex_;
221     DisplayId defaultDisplayId_;
222 
Init()223     void Init()
224     {
225         std::lock_guard<std::recursive_mutex> lock(mutex_);
226         (void)rsInterface_.SetScreenChangeCallback([this](ScreenId id, ScreenEvent event) {
227             switch (event) {
228                 case ScreenEvent::CONNECTED: {
229                     this->OnDisplayConnected(id);
230                     break;
231                 }
232                 case ScreenEvent::DISCONNECTED: {
233                     this->OnDisplayDisConnected(id);
234                     break;
235                 }
236                 default:
237                     break;
238             }
239         });
240 
241         defaultDisplayId_ = rsInterface_.GetDefaultScreenId();
242         displays_[defaultDisplayId_] =
243             Display { defaultDisplayId_, rsInterface_.GetScreenActiveMode(defaultDisplayId_) };
244     }
245 };
246 MyDMS g_dms;
247 
main()248 int main()
249 {
250     DisplayId id = g_dms.GetDefaultDisplayId();
251     cout << "RS default screen id is " << id << ".\n";
252     ROSEN_LOGD("***SurfaceCaptureTest*** main: begin");
253 
254     auto surfaceLauncher = CreateSurface();
255     auto surfaceNode1 = CreateSurface();
256     auto surfaceNode2 = CreateSurface();
257     auto surfaceNode3 = CreateSurface();
258     DrawSurface(Drawing::Rect(0, 0, 700, 1000), 0xFFF0FFF0, Drawing::Rect(0, 0, 7000, 1000), surfaceLauncher);
259     DrawSurface(Drawing::Rect(100, 300, 228, 428), 0xFF8B008B, Drawing::Rect(20, 20, 120, 120), surfaceNode1);
260     DrawSurface(Drawing::Rect(100, 600, 356, 856), 0xFF00FF40, Drawing::Rect(20, 20, 120, 120), surfaceNode3);
261     DrawSurfaceToCapture(surfaceNode2);
262     RSDisplayNodeConfig config;
263     config.screenId = id;
264     RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(config);
265     displayNode->AddChild(surfaceLauncher, -1);
266     displayNode->AddChild(surfaceNode1, -1);
267     displayNode->AddChild(surfaceNode2, -1);
268     displayNode->AddChild(surfaceNode3, -1);
269     RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
270 
271     class TestSurfaceCapture : public SurfaceCaptureCallback {
272     public:
273         explicit TestSurfaceCapture(std::shared_ptr<RSSurfaceNode> surfaceNode) : showNode_(surfaceNode) {}
274         ~TestSurfaceCapture() override {}
275         void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelmap) override
276         {
277             DrawPixelmap(showNode_, pixelmap);
278         }
279     private:
280         std::shared_ptr<RSSurfaceNode> showNode_;
281     };
282     sleep(2);
283     std::shared_ptr<SurfaceCaptureCallback> cb = make_shared<TestSurfaceCapture>(surfaceNode1);
284     RSSurfaceCaptureConfig captureConfig;
285     g_dms.rsInterface_.TakeSurfaceCapture(surfaceNode2, cb, captureConfig);
286     sleep(2);
287     std::shared_ptr<SurfaceCaptureCallback> cb2 = make_shared<TestSurfaceCapture>(surfaceNode3);
288     g_dms.rsInterface_.TakeSurfaceCapture(displayNode, cb2, captureConfig);
289     ROSEN_LOGD("***SurfaceCaptureTest*** main: end");
290     return 0;
291 }