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