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 "pipeline/rs_recording_canvas.h"
17 #include "pipeline/rs_draw_cmd.h"
18 #include "recording/cmd_list_helper.h"
19 #include "render/rs_pixel_map_util.h"
20
21 namespace OHOS {
22 namespace Rosen {
23
ExtendRecordingCanvas(int32_t width,int32_t height,bool addDrawOpImmediate)24 ExtendRecordingCanvas::ExtendRecordingCanvas(int32_t width, int32_t height, bool addDrawOpImmediate)
25 : Drawing::RecordingCanvas(width, height, addDrawOpImmediate) {}
26
Obtain(int32_t width,int32_t height,bool addDrawOpImmediate)27 std::unique_ptr<ExtendRecordingCanvas> ExtendRecordingCanvas::Obtain(int32_t width, int32_t height,
28 bool addDrawOpImmediate)
29 {
30 std::unique_ptr<ExtendRecordingCanvas> canvas = nullptr;
31 {
32 std::lock_guard<std::mutex> lock(canvasMutex_);
33 if (canvasPool_.empty()) {
34 return std::make_unique<ExtendRecordingCanvas>(width, height, addDrawOpImmediate);
35 }
36 canvas = std::move(canvasPool_.front());
37 canvasPool_.pop();
38 }
39
40 if (!canvas) {
41 canvas = std::make_unique<ExtendRecordingCanvas>(width, height, addDrawOpImmediate);
42 } else {
43 canvas->Reset(width, height, addDrawOpImmediate);
44 }
45 return canvas;
46 }
47
Recycle(std::unique_ptr<ExtendRecordingCanvas> & canvas)48 void ExtendRecordingCanvas::Recycle(std::unique_ptr<ExtendRecordingCanvas>& canvas)
49 {
50 std::lock_guard<std::mutex> lock(canvasMutex_);
51 if (canvasPool_.size() >= MAX_CANVAS_SIZE) {
52 return;
53 }
54 canvasPool_.push(std::move(canvas));
55 }
56
DrawImageWithParm(const std::shared_ptr<Drawing::Image> & image,const std::shared_ptr<Drawing::Data> & data,const Drawing::AdaptiveImageInfo & rsImageInfo,const Drawing::SamplingOptions & sampling)57 void ExtendRecordingCanvas::DrawImageWithParm(
58 const std::shared_ptr<Drawing::Image>& image, const std::shared_ptr<Drawing::Data>& data,
59 const Drawing::AdaptiveImageInfo& rsImageInfo, const Drawing::SamplingOptions& sampling)
60 {
61 if (!addDrawOpImmediate_) {
62 AddDrawOpDeferred<Drawing::DrawImageWithParmOpItem>(image, data, rsImageInfo, sampling);
63 return;
64 }
65 auto object = std::make_shared<RSExtendImageObject>(image, data, rsImageInfo);
66 auto drawCallList = Drawing::RecordingCanvas::GetDrawCmdList();
67 auto objectHandle =
68 Drawing::CmdListHelper::AddImageObjectToCmdList(*drawCallList, object);
69 AddDrawOpImmediate<Drawing::DrawImageWithParmOpItem::ConstructorHandle>(objectHandle, sampling);
70 }
71
DrawPixelMapWithParm(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::AdaptiveImageInfo & rsImageInfo,const Drawing::SamplingOptions & sampling)72 void ExtendRecordingCanvas::DrawPixelMapWithParm(const std::shared_ptr<Media::PixelMap>& pixelMap,
73 const Drawing::AdaptiveImageInfo& rsImageInfo, const Drawing::SamplingOptions& sampling)
74 {
75 if (!addDrawOpImmediate_) {
76 AddDrawOpDeferred<Drawing::DrawPixelMapWithParmOpItem>(pixelMap, rsImageInfo, sampling);
77 return;
78 }
79 auto object = std::make_shared<RSExtendImageObject>(pixelMap, rsImageInfo);
80 auto drawCallList = Drawing::RecordingCanvas::GetDrawCmdList();
81 auto objectHandle =
82 Drawing::CmdListHelper::AddImageObjectToCmdList(*drawCallList, object);
83 AddDrawOpImmediate<Drawing::DrawPixelMapWithParmOpItem::ConstructorHandle>(objectHandle, sampling);
84 }
85
DrawPixelMapRect(const std::shared_ptr<Media::PixelMap> & pixelMap,const Drawing::Rect & src,const Drawing::Rect & dst,const Drawing::SamplingOptions & sampling,Drawing::SrcRectConstraint constraint)86 void ExtendRecordingCanvas::DrawPixelMapRect(const std::shared_ptr<Media::PixelMap>& pixelMap, const Drawing::Rect& src,
87 const Drawing::Rect& dst, const Drawing::SamplingOptions& sampling,
88 Drawing::SrcRectConstraint constraint)
89 {
90 if (!addDrawOpImmediate_) {
91 AddDrawOpDeferred<Drawing::DrawPixelMapRectOpItem>(pixelMap, src, dst, sampling, constraint);
92 return;
93 }
94 auto object = std::make_shared<RSExtendImageBaseObj>(pixelMap, src, dst);
95 auto drawCallList = Drawing::RecordingCanvas::GetDrawCmdList();
96 auto objectHandle =
97 Drawing::CmdListHelper::AddImageBaseObjToCmdList(*drawCallList, object);
98 AddDrawOpImmediate<Drawing::DrawPixelMapRectOpItem::ConstructorHandle>(objectHandle, sampling, constraint);
99 }
100
DrawDrawFunc(Drawing::RecordingCanvas::DrawFunc && drawFunc)101 void ExtendRecordingCanvas::DrawDrawFunc(Drawing::RecordingCanvas::DrawFunc&& drawFunc)
102 {
103 if (!addDrawOpImmediate_) {
104 cmdList_->AddDrawOp(std::make_shared<Drawing::DrawFuncOpItem>(std::move(drawFunc)));
105 return;
106 }
107 auto object = std::make_shared<RSExtendDrawFuncObj>(std::move(drawFunc));
108 auto drawCallList = Drawing::RecordingCanvas::GetDrawCmdList();
109 auto objectHandle =
110 Drawing::CmdListHelper::AddDrawFuncObjToCmdList(*drawCallList, object);
111 cmdList_->AddOp<Drawing::DrawFuncOpItem::ConstructorHandle>(objectHandle);
112 }
113
114 #ifdef ROSEN_OHOS
DrawSurfaceBuffer(const DrawingSurfaceBufferInfo & surfaceBufferInfo)115 void ExtendRecordingCanvas::DrawSurfaceBuffer(const DrawingSurfaceBufferInfo& surfaceBufferInfo)
116 {
117 if (!addDrawOpImmediate_) {
118 AddDrawOpDeferred<Drawing::DrawSurfaceBufferOpItem>(surfaceBufferInfo);
119 return;
120 }
121 std::shared_ptr<Drawing::SurfaceBufferEntry> surfaceBufferEntry = std::make_shared<Drawing::SurfaceBufferEntry>(
122 surfaceBufferInfo.surfaceBuffer_, surfaceBufferInfo.acquireFence_);
123 Drawing::Rect srcRect = surfaceBufferInfo.srcRect_;
124 if ((srcRect.GetWidth() <= 0 || srcRect.GetHeight() <= 0) && surfaceBufferInfo.surfaceBuffer_) {
125 srcRect = Drawing::Rect { 0, 0, surfaceBufferInfo.surfaceBuffer_->GetWidth(),
126 surfaceBufferInfo.surfaceBuffer_->GetHeight() };
127 }
128 AddDrawOpImmediate<Drawing::DrawSurfaceBufferOpItem::ConstructorHandle>(
129 Drawing::CmdListHelper::AddSurfaceBufferEntryToCmdList(*cmdList_, surfaceBufferEntry),
130 surfaceBufferInfo.dstRect_.GetLeft(), surfaceBufferInfo.dstRect_.GetTop(),
131 surfaceBufferInfo.dstRect_.GetWidth(), surfaceBufferInfo.dstRect_.GetHeight(), surfaceBufferInfo.pid_,
132 surfaceBufferInfo.uid_, srcRect);
133 }
134 #endif
135
136 template<typename T, typename... Args>
AddDrawOpImmediate(Args &&...args)137 void ExtendRecordingCanvas::AddDrawOpImmediate(Args&&... args)
138 {
139 bool brushValid = paintBrush_.IsValid();
140 bool penValid = paintPen_.IsValid();
141 if (!brushValid && !penValid) {
142 Drawing::PaintHandle paintHandle;
143 paintHandle.isAntiAlias = true;
144 paintHandle.style = Drawing::Paint::PaintStyle::PAINT_FILL;
145 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
146 return;
147 }
148 if (brushValid && penValid && Drawing::Paint::CanCombinePaint(paintBrush_, paintPen_)) {
149 Drawing::PaintHandle paintHandle;
150 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_FILL_STROKE);
151 Drawing::DrawOpItem::GenerateHandleFromPaint(*cmdList_, paintPen_, paintHandle);
152 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
153 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_STROKE);
154 return;
155 }
156 if (brushValid) {
157 Drawing::PaintHandle paintHandle;
158 Drawing::DrawOpItem::GenerateHandleFromPaint(*cmdList_, paintBrush_, paintHandle);
159 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
160 }
161 if (penValid) {
162 Drawing::PaintHandle paintHandle;
163 Drawing::DrawOpItem::GenerateHandleFromPaint(*cmdList_, paintPen_, paintHandle);
164 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
165 }
166 }
167
168 template<typename T, typename... Args>
AddDrawOpDeferred(Args &&...args)169 void ExtendRecordingCanvas::AddDrawOpDeferred(Args&&... args)
170 {
171 bool brushValid = paintBrush_.IsValid();
172 bool penValid = paintPen_.IsValid();
173 if (!brushValid && !penValid) {
174 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., defaultPaint_));
175 return;
176 }
177 if (brushValid && penValid && Drawing::Paint::CanCombinePaint(paintBrush_, paintPen_)) {
178 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_FILL_STROKE);
179 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., paintPen_));
180 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_STROKE);
181 return;
182 }
183 if (brushValid) {
184 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., paintBrush_));
185 }
186 if (penValid) {
187 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., paintPen_));
188 }
189 }
190
DrawImageNineWithPixelMap(const std::shared_ptr<Media::PixelMap> & pixelmap,const Drawing::RectI & center,const Drawing::Rect & dst,Drawing::FilterMode filter,const Drawing::Brush * brush)191 void ExtendRecordingCanvas::DrawImageNineWithPixelMap(const std::shared_ptr<Media::PixelMap>& pixelmap,
192 const Drawing::RectI& center, const Drawing::Rect& dst, Drawing::FilterMode filter, const Drawing::Brush* brush)
193 {
194 auto image = RSPixelMapUtil::ExtractDrawingImage(pixelmap);
195 Drawing::RecordingCanvas::DrawImageNine(image.get(), center, dst, filter, brush);
196 }
197 } // namespace Rosen
198 } // namespace OHOS
199