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 AddDrawOpImmediate<Drawing::DrawSurfaceBufferOpItem::ConstructorHandle>(
124 Drawing::CmdListHelper::AddSurfaceBufferEntryToCmdList(*cmdList_, surfaceBufferEntry),
125 surfaceBufferInfo.offSetX_, surfaceBufferInfo.offSetY_,
126 surfaceBufferInfo.width_, surfaceBufferInfo.height_, surfaceBufferInfo.pid_, surfaceBufferInfo.uid_);
127 }
128 #endif
129
130 template<typename T, typename... Args>
AddDrawOpImmediate(Args &&...args)131 void ExtendRecordingCanvas::AddDrawOpImmediate(Args&&... args)
132 {
133 bool brushValid = paintBrush_.IsValid();
134 bool penValid = paintPen_.IsValid();
135 if (!brushValid && !penValid) {
136 Drawing::PaintHandle paintHandle;
137 paintHandle.isAntiAlias = true;
138 paintHandle.style = Drawing::Paint::PaintStyle::PAINT_FILL;
139 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
140 return;
141 }
142 if (brushValid && penValid && Drawing::Paint::CanCombinePaint(paintBrush_, paintPen_)) {
143 Drawing::PaintHandle paintHandle;
144 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_FILL_STROKE);
145 Drawing::DrawOpItem::GenerateHandleFromPaint(*cmdList_, paintPen_, paintHandle);
146 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
147 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_STROKE);
148 return;
149 }
150 if (brushValid) {
151 Drawing::PaintHandle paintHandle;
152 Drawing::DrawOpItem::GenerateHandleFromPaint(*cmdList_, paintBrush_, paintHandle);
153 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
154 }
155 if (penValid) {
156 Drawing::PaintHandle paintHandle;
157 Drawing::DrawOpItem::GenerateHandleFromPaint(*cmdList_, paintPen_, paintHandle);
158 cmdList_->AddDrawOp<T>(std::forward<Args>(args)..., paintHandle);
159 }
160 }
161
162 template<typename T, typename... Args>
AddDrawOpDeferred(Args &&...args)163 void ExtendRecordingCanvas::AddDrawOpDeferred(Args&&... args)
164 {
165 bool brushValid = paintBrush_.IsValid();
166 bool penValid = paintPen_.IsValid();
167 if (!brushValid && !penValid) {
168 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., defaultPaint_));
169 return;
170 }
171 if (brushValid && penValid && Drawing::Paint::CanCombinePaint(paintBrush_, paintPen_)) {
172 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_FILL_STROKE);
173 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., paintPen_));
174 paintPen_.SetStyle(Drawing::Paint::PaintStyle::PAINT_STROKE);
175 return;
176 }
177 if (brushValid) {
178 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., paintBrush_));
179 }
180 if (penValid) {
181 cmdList_->AddDrawOp(std::make_shared<T>(std::forward<Args>(args)..., paintPen_));
182 }
183 }
184
DrawImageNineWithPixelMap(const std::shared_ptr<Media::PixelMap> & pixelmap,const Drawing::RectI & center,const Drawing::Rect & dst,Drawing::FilterMode filter,const Drawing::Brush * brush)185 void ExtendRecordingCanvas::DrawImageNineWithPixelMap(const std::shared_ptr<Media::PixelMap>& pixelmap,
186 const Drawing::RectI& center, const Drawing::Rect& dst, Drawing::FilterMode filter, const Drawing::Brush* brush)
187 {
188 auto image = RSPixelMapUtil::ExtractDrawingImage(pixelmap);
189 Drawing::RecordingCanvas::DrawImageNine(image.get(), center, dst, filter, brush);
190 }
191 } // namespace Rosen
192 } // namespace OHOS
193