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
18 #include "pipeline/rs_draw_cmd.h"
19 #include "platform/common/rs_log.h"
20 #include "platform/common/rs_system_properties.h"
21
22 namespace OHOS {
23 namespace Rosen {
RSRecordingCanvas(int width,int height)24 RSRecordingCanvas::RSRecordingCanvas(int width, int height) : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(width, height)
25 {
26 drawCmdList_ = std::make_shared<DrawCmdList>(width, height);
27 }
28
~RSRecordingCanvas()29 RSRecordingCanvas::~RSRecordingCanvas() {}
30
GetDrawCmdList() const31 std::shared_ptr<DrawCmdList> RSRecordingCanvas::GetDrawCmdList() const
32 {
33 return drawCmdList_;
34 }
35
Clear() const36 void RSRecordingCanvas::Clear() const
37 {
38 if (drawCmdList_ == nullptr) {
39 return;
40 }
41 drawCmdList_->ClearOp();
42 }
43
AddOp(std::unique_ptr<OpItem> && opItem)44 void RSRecordingCanvas::AddOp(std::unique_ptr<OpItem>&& opItem)
45 {
46 if (drawCmdList_ == nullptr || opItem == nullptr) {
47 ROSEN_LOGE("RSRecordingCanvas:AddOp, drawCmdList_ or opItem is nullptr");
48 return;
49 }
50 drawCmdList_->AddOp(std::move(opItem));
51 }
52
getGrContext()53 GrContext* RSRecordingCanvas::getGrContext()
54 {
55 return grContext_;
56 }
57
SetGrContext(GrContext * grContext)58 void RSRecordingCanvas::SetGrContext(GrContext* grContext)
59 {
60 grContext_ = grContext;
61 }
62
onNewSurface(const SkImageInfo & info,const SkSurfaceProps & props)63 sk_sp<SkSurface> RSRecordingCanvas::onNewSurface(const SkImageInfo& info, const SkSurfaceProps& props)
64 {
65 return nullptr;
66 }
67
onFlush()68 void RSRecordingCanvas::onFlush()
69 {
70 std::unique_ptr<OpItem> op = std::make_unique<FlushOpItem>();
71 AddOp(std::move(op));
72 }
73
willSave()74 void RSRecordingCanvas::willSave()
75 {
76 std::unique_ptr<OpItem> op = std::make_unique<SaveOpItem>();
77 AddOp(std::move(op));
78 saveCount_++;
79 }
80
getSaveLayerStrategy(const SaveLayerRec & rec)81 SkCanvas::SaveLayerStrategy RSRecordingCanvas::getSaveLayerStrategy(const SaveLayerRec& rec)
82 {
83 std::unique_ptr<OpItem> op = std::make_unique<SaveLayerOpItem>(rec);
84 AddOp(std::move(op));
85 saveCount_++;
86 return SkCanvas::kNoLayer_SaveLayerStrategy;
87 }
88
willRestore()89 void RSRecordingCanvas::willRestore()
90 {
91 if (saveCount_ > 0) {
92 std::unique_ptr<OpItem> op = std::make_unique<RestoreOpItem>();
93 AddOp(std::move(op));
94 --saveCount_;
95 }
96 }
97
didConcat(const SkMatrix & matrix)98 void RSRecordingCanvas::didConcat(const SkMatrix& matrix)
99 {
100 std::unique_ptr<OpItem> op = std::make_unique<ConcatOpItem>(matrix);
101 AddOp(std::move(op));
102 }
103
didSetMatrix(const SkMatrix & matrix)104 void RSRecordingCanvas::didSetMatrix(const SkMatrix& matrix)
105 {
106 std::unique_ptr<OpItem> op = std::make_unique<MatrixOpItem>(matrix);
107 AddOp(std::move(op));
108 }
109
didTranslate(SkScalar dx,SkScalar dy)110 void RSRecordingCanvas::didTranslate(SkScalar dx, SkScalar dy)
111 {
112 std::unique_ptr<OpItem> op = std::make_unique<TranslateOpItem>(dx, dy);
113 AddOp(std::move(op));
114 }
115
onClipRect(const SkRect & rect,SkClipOp clipOp,ClipEdgeStyle style)116 void RSRecordingCanvas::onClipRect(const SkRect& rect, SkClipOp clipOp, ClipEdgeStyle style)
117 {
118 std::unique_ptr<OpItem> op = std::make_unique<ClipRectOpItem>(rect, clipOp, style == kSoft_ClipEdgeStyle);
119 AddOp(std::move(op));
120 }
121
onClipRRect(const SkRRect & rrect,SkClipOp clipOp,ClipEdgeStyle style)122 void RSRecordingCanvas::onClipRRect(const SkRRect& rrect, SkClipOp clipOp, ClipEdgeStyle style)
123 {
124 std::unique_ptr<OpItem> op = std::make_unique<ClipRRectOpItem>(rrect, clipOp, style == kSoft_ClipEdgeStyle);
125 AddOp(std::move(op));
126 }
127
onClipPath(const SkPath & path,SkClipOp clipOp,ClipEdgeStyle style)128 void RSRecordingCanvas::onClipPath(const SkPath& path, SkClipOp clipOp, ClipEdgeStyle style)
129 {
130 std::unique_ptr<OpItem> op = std::make_unique<ClipPathOpItem>(path, clipOp, style == kSoft_ClipEdgeStyle);
131 AddOp(std::move(op));
132 }
133
onClipRegion(const SkRegion & region,SkClipOp clipop)134 void RSRecordingCanvas::onClipRegion(const SkRegion& region, SkClipOp clipop)
135 {
136 std::unique_ptr<OpItem> op = std::make_unique<ClipRegionOpItem>(region, clipop);
137 AddOp(std::move(op));
138 }
139
onDrawPaint(const SkPaint & paint)140 void RSRecordingCanvas::onDrawPaint(const SkPaint& paint)
141 {
142 std::unique_ptr<OpItem> op = std::make_unique<PaintOpItem>(paint);
143 AddOp(std::move(op));
144 }
145
DrawImageWithParm(const sk_sp<SkImage> img,const sk_sp<SkData> data,const Rosen::RsImageInfo & rsimageInfo,const SkPaint & paint)146 void RSRecordingCanvas::DrawImageWithParm(const sk_sp<SkImage>img, const sk_sp<SkData> data,
147 const Rosen::RsImageInfo& rsimageInfo, const SkPaint& paint)
148 {
149 std::unique_ptr<OpItem> op = std::make_unique<ImageWithParmOpItem>(img, data, rsimageInfo, paint);
150 AddOp(std::move(op));
151 }
152
DrawPixelMap(const std::shared_ptr<Media::PixelMap> & pixelmap,SkScalar x,SkScalar y,const SkPaint * paint)153 void RSRecordingCanvas::DrawPixelMap(
154 const std::shared_ptr<Media::PixelMap>& pixelmap, SkScalar x, SkScalar y, const SkPaint* paint)
155 {
156 std::unique_ptr<OpItem> op = std::make_unique<PixelMapOpItem>(pixelmap, x, y, paint);
157 AddOp(std::move(op));
158 }
159
DrawPixelMapRect(const std::shared_ptr<Media::PixelMap> & pixelmap,const SkRect & src,const SkRect & dst,const SkPaint * paint,SrcRectConstraint constraint)160 void RSRecordingCanvas::DrawPixelMapRect(const std::shared_ptr<Media::PixelMap>& pixelmap, const SkRect& src,
161 const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint)
162 {
163 std::unique_ptr<OpItem> op = std::make_unique<PixelMapRectOpItem>(pixelmap, src, dst, paint);
164 AddOp(std::move(op));
165 }
166
DrawPixelMapRect(const std::shared_ptr<Media::PixelMap> & pixelmap,const SkRect & dst,const SkPaint * paint)167 void RSRecordingCanvas::DrawPixelMapRect(
168 const std::shared_ptr<Media::PixelMap>& pixelmap, const SkRect& dst, const SkPaint* paint)
169 {
170 DrawPixelMapRect(pixelmap, SkRect::MakeIWH(pixelmap->GetWidth(), pixelmap->GetHeight()), dst, paint);
171 }
172
DrawPixelMapWithParm(const std::shared_ptr<Media::PixelMap> & pixelmap,const Rosen::RsImageInfo & rsImageInfo,const SkPaint & paint)173 void RSRecordingCanvas::DrawPixelMapWithParm(
174 const std::shared_ptr<Media::PixelMap>& pixelmap, const Rosen::RsImageInfo& rsImageInfo, const SkPaint& paint)
175 {
176 std::unique_ptr<OpItem> op = std::make_unique<ImageWithParmOpItem>(pixelmap, rsImageInfo, paint);
177 AddOp(std::move(op));
178 }
179
onDrawBehind(const SkPaint & paint)180 void RSRecordingCanvas::onDrawBehind(const SkPaint& paint)
181 {
182 // [PLANNING]: To be implemented
183 ROSEN_LOGE("RSRecordingCanvas::onDrawBehind not support yet");
184 }
185
onDrawPath(const SkPath & path,const SkPaint & paint)186 void RSRecordingCanvas::onDrawPath(const SkPath& path, const SkPaint& paint)
187 {
188 std::unique_ptr<OpItem> op = std::make_unique<PathOpItem>(path, paint);
189 if (RSSystemProperties::GetDrawTextAsBitmap()) {
190 // replace drawOpItem with cached one (generated by CPU)
191 op = op->GenerateCachedOpItem(nullptr);
192 }
193 AddOp(std::move(op));
194 }
195
onDrawRect(const SkRect & rect,const SkPaint & paint)196 void RSRecordingCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint)
197 {
198 std::unique_ptr<OpItem> op = std::make_unique<RectOpItem>(rect, paint);
199 AddOp(std::move(op));
200 }
201
onDrawRegion(const SkRegion & region,const SkPaint & paint)202 void RSRecordingCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint)
203 {
204 std::unique_ptr<OpItem> op = std::make_unique<RegionOpItem>(region, paint);
205 AddOp(std::move(op));
206 }
207
onDrawOval(const SkRect & oval,const SkPaint & paint)208 void RSRecordingCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint)
209 {
210 std::unique_ptr<OpItem> op = std::make_unique<OvalOpItem>(oval, paint);
211 AddOp(std::move(op));
212 }
213
onDrawArc(const SkRect & oval,SkScalar startAngle,SkScalar sweepAngle,bool useCenter,const SkPaint & paint)214 void RSRecordingCanvas::onDrawArc(
215 const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const SkPaint& paint)
216 {
217 std::unique_ptr<OpItem> op = std::make_unique<ArcOpItem>(oval, startAngle, sweepAngle, useCenter, paint);
218 AddOp(std::move(op));
219 }
220
onDrawRRect(const SkRRect & rrect,const SkPaint & paint)221 void RSRecordingCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint)
222 {
223 std::unique_ptr<OpItem> op = std::make_unique<RoundRectOpItem>(rrect, paint);
224 AddOp(std::move(op));
225 }
226
onDrawDRRect(const SkRRect & out,const SkRRect & in,const SkPaint & paint)227 void RSRecordingCanvas::onDrawDRRect(const SkRRect& out, const SkRRect& in, const SkPaint& paint)
228 {
229 std::unique_ptr<OpItem> op = std::make_unique<DRRectOpItem>(out, in, paint);
230 AddOp(std::move(op));
231 }
232
onDrawDrawable(SkDrawable * drawable,const SkMatrix * matrix)233 void RSRecordingCanvas::onDrawDrawable(SkDrawable* drawable, const SkMatrix* matrix)
234 {
235 std::unique_ptr<OpItem> op = std::make_unique<DrawableOpItem>(drawable, matrix);
236 AddOp(std::move(op));
237 }
238
onDrawPicture(const SkPicture * picture,const SkMatrix * matrix,const SkPaint * paint)239 void RSRecordingCanvas::onDrawPicture(const SkPicture* picture, const SkMatrix* matrix, const SkPaint* paint)
240 {
241 std::unique_ptr<OpItem> op = std::make_unique<PictureOpItem>(sk_ref_sp(picture), matrix, paint);
242 AddOp(std::move(op));
243 }
244
onDrawAnnotation(const SkRect & rect,const char key[],SkData * val)245 void RSRecordingCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* val)
246 {
247 // [PLANNING]: To be implemented
248 ROSEN_LOGE("RSRecordingCanvas::onDrawAnnotation not support yet");
249 }
250
onDrawTextBlob(const SkTextBlob * blob,SkScalar x,SkScalar y,const SkPaint & paint)251 void RSRecordingCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint)
252 {
253 std::unique_ptr<OpItem> op = std::make_unique<TextBlobOpItem>(sk_ref_sp(blob), x, y, paint);
254 if (RSSystemProperties::GetDrawTextAsBitmap()) {
255 // replace drawOpItem with cached one (generated by CPU)
256 op = op->GenerateCachedOpItem(nullptr);
257 }
258 AddOp(std::move(op));
259 }
260
onDrawBitmap(const SkBitmap & bm,SkScalar x,SkScalar y,const SkPaint * paint)261 void RSRecordingCanvas::onDrawBitmap(const SkBitmap& bm, SkScalar x, SkScalar y, const SkPaint* paint)
262 {
263 std::unique_ptr<OpItem> op = std::make_unique<BitmapOpItem>(SkImage::MakeFromBitmap(bm), x, y, paint);
264 AddOp(std::move(op));
265 }
266
onDrawBitmapNine(const SkBitmap & bm,const SkIRect & center,const SkRect & dst,const SkPaint * paint)267 void RSRecordingCanvas::onDrawBitmapNine(
268 const SkBitmap& bm, const SkIRect& center, const SkRect& dst, const SkPaint* paint)
269 {
270 std::unique_ptr<OpItem> op = std::make_unique<BitmapNineOpItem>(SkImage::MakeFromBitmap(bm), center, dst, paint);
271 AddOp(std::move(op));
272 }
273
onDrawBitmapRect(const SkBitmap & bm,const SkRect * src,const SkRect & dst,const SkPaint * paint,SrcRectConstraint constraint)274 void RSRecordingCanvas::onDrawBitmapRect(
275 const SkBitmap& bm, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint)
276 {
277 std::unique_ptr<OpItem> op = std::make_unique<BitmapRectOpItem>(SkImage::MakeFromBitmap(bm), src, dst, paint);
278 AddOp(std::move(op));
279 }
280
onDrawBitmapLattice(const SkBitmap & bm,const SkCanvas::Lattice & lattice,const SkRect & dst,const SkPaint * paint)281 void RSRecordingCanvas::onDrawBitmapLattice(
282 const SkBitmap& bm, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint)
283 {
284 // use DrawImageLatticeAsBitmap instead of BitmapLatticeOpItem
285 sk_sp<SkImage> image = SkImage::MakeFromBitmap(bm);
286 DrawImageLatticeAsBitmap(image.get(), lattice, dst, paint);
287 }
288
onDrawImage(const SkImage * img,SkScalar x,SkScalar y,const SkPaint * paint)289 void RSRecordingCanvas::onDrawImage(const SkImage* img, SkScalar x, SkScalar y, const SkPaint* paint)
290 {
291 std::unique_ptr<OpItem> op = std::make_unique<BitmapOpItem>(sk_ref_sp(img), x, y, paint);
292 AddOp(std::move(op));
293 }
294
onDrawImageNine(const SkImage * img,const SkIRect & center,const SkRect & dst,const SkPaint * paint)295 void RSRecordingCanvas::onDrawImageNine(
296 const SkImage* img, const SkIRect& center, const SkRect& dst, const SkPaint* paint)
297 {
298 std::unique_ptr<OpItem> op = std::make_unique<BitmapNineOpItem>(sk_ref_sp(img), center, dst, paint);
299 AddOp(std::move(op));
300 }
301
onDrawImageRect(const SkImage * img,const SkRect * src,const SkRect & dst,const SkPaint * paint,SrcRectConstraint constraint)302 void RSRecordingCanvas::onDrawImageRect(
303 const SkImage* img, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint)
304 {
305 std::unique_ptr<OpItem> op = std::make_unique<BitmapRectOpItem>(sk_ref_sp(img), src, dst, paint);
306 AddOp(std::move(op));
307 }
308
onDrawImageLattice(const SkImage * img,const SkCanvas::Lattice & lattice,const SkRect & dst,const SkPaint * paint)309 void RSRecordingCanvas::onDrawImageLattice(
310 const SkImage* img, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint)
311 {
312 // use DrawImageLatticeAsBitmap instead of BitmapLatticeOpItem
313 DrawImageLatticeAsBitmap(img, lattice, dst, paint);
314 }
315
DrawImageLatticeAsBitmap(const SkImage * image,const SkCanvas::Lattice & lattice,const SkRect & dst,const SkPaint * paint)316 void RSRecordingCanvas::DrawImageLatticeAsBitmap(
317 const SkImage* image, const SkCanvas::Lattice& lattice, const SkRect& dst, const SkPaint* paint)
318 {
319 SkBitmap bitmap;
320 auto imageInfo = SkImageInfo::Make(dst.width(), dst.height(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
321 bitmap.allocPixels(imageInfo);
322 SkCanvas tempCanvas(bitmap);
323 // align to [0, 0]
324 tempCanvas.translate(-dst.left(), -dst.top());
325 tempCanvas.drawImageLattice(image, lattice, dst, paint);
326 tempCanvas.flush();
327 // draw on canvas with correct offset
328 drawBitmap(bitmap, dst.left(), dst.top());
329 }
330
DrawAdaptiveRRect(float radius,const SkPaint & paint)331 void RSRecordingCanvas::DrawAdaptiveRRect(float radius, const SkPaint& paint)
332 {
333 std::unique_ptr<OpItem> op = std::make_unique<AdaptiveRRectOpItem>(radius, paint);
334 AddOp(std::move(op));
335 }
336
DrawAdaptiveRRectScale(float radiusRatio,const SkPaint & paint)337 void RSRecordingCanvas::DrawAdaptiveRRectScale(float radiusRatio, const SkPaint& paint)
338 {
339 std::unique_ptr<OpItem> op = std::make_unique<AdaptiveRRectScaleOpItem>(radiusRatio, paint);
340 AddOp(std::move(op));
341 }
342
ClipAdaptiveRRect(const SkVector radius[])343 void RSRecordingCanvas::ClipAdaptiveRRect(const SkVector radius[])
344 {
345 std::unique_ptr<OpItem> op = std::make_unique<ClipAdaptiveRRectOpItem>(radius);
346 AddOp(std::move(op));
347 }
348
ClipOutsetRect(float dx,float dy)349 void RSRecordingCanvas::ClipOutsetRect(float dx, float dy)
350 {
351 std::unique_ptr<OpItem> op = std::make_unique<ClipOutsetRectOpItem>(dx, dy);
352 AddOp(std::move(op));
353 }
354
onDrawPatch(const SkPoint cubics[12],const SkColor colors[4],const SkPoint texCoords[4],SkBlendMode bmode,const SkPaint & paint)355 void RSRecordingCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4],
356 SkBlendMode bmode, const SkPaint& paint)
357 {
358 // [PLANNING]: To be implemented
359 ROSEN_LOGE("RSRecordingCanvas::onDrawPatch not support yet");
360 }
361
onDrawPoints(SkCanvas::PointMode mode,size_t count,const SkPoint pts[],const SkPaint & paint)362 void RSRecordingCanvas::onDrawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint pts[], const SkPaint& paint)
363 {
364 std::unique_ptr<OpItem> op = std::make_unique<PointsOpItem>(mode, count, pts, paint);
365 AddOp(std::move(op));
366 }
367
onDrawVerticesObject(const SkVertices * vertices,const SkVertices::Bone bones[],int boneCount,SkBlendMode mode,const SkPaint & paint)368 void RSRecordingCanvas::onDrawVerticesObject(
369 const SkVertices* vertices, const SkVertices::Bone bones[], int boneCount, SkBlendMode mode, const SkPaint& paint)
370 {
371 std::unique_ptr<OpItem> op = std::make_unique<VerticesOpItem>(vertices, bones, boneCount, mode, paint);
372 AddOp(std::move(op));
373 }
374
onDrawAtlas(const SkImage * atlas,const SkRSXform xforms[],const SkRect texs[],const SkColor colors[],int count,SkBlendMode bmode,const SkRect * cull,const SkPaint * paint)375 void RSRecordingCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xforms[], const SkRect texs[],
376 const SkColor colors[], int count, SkBlendMode bmode, const SkRect* cull, const SkPaint* paint)
377 {
378 // [PLANNING]: To be implemented
379 ROSEN_LOGE("RSRecordingCanvas::onDrawAtlas not support yet");
380 }
381
onDrawShadowRec(const SkPath & path,const SkDrawShadowRec & rec)382 void RSRecordingCanvas::onDrawShadowRec(const SkPath& path, const SkDrawShadowRec& rec)
383 {
384 std::unique_ptr<OpItem> op = std::make_unique<ShadowRecOpItem>(path, rec);
385 AddOp(std::move(op));
386 }
387
MultiplyAlpha(float alpha)388 void RSRecordingCanvas::MultiplyAlpha(float alpha)
389 {
390 std::unique_ptr<OpItem> op = std::make_unique<MultiplyAlphaOpItem>(alpha);
391 AddOp(std::move(op));
392 }
393
SaveAlpha()394 void RSRecordingCanvas::SaveAlpha()
395 {
396 std::unique_ptr<OpItem> op = std::make_unique<SaveAlphaOpItem>();
397 AddOp(std::move(op));
398 }
399
RestoreAlpha()400 void RSRecordingCanvas::RestoreAlpha()
401 {
402 std::unique_ptr<OpItem> op = std::make_unique<RestoreAlphaOpItem>();
403 AddOp(std::move(op));
404 }
405 } // namespace Rosen
406 } // namespace OHOS
407