1 /*
2 * Copyright (c) 2023 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 "recording/shader_effect_cmd_list.h"
17
18 #include "recording/cmd_list_helper.h"
19 #include "image/image.h"
20 #include "utils/log.h"
21
22 namespace OHOS {
23 namespace Rosen {
24 namespace Drawing {
CreateFromData(const CmdListData & data,bool isCopy)25 std::shared_ptr<ShaderEffectCmdList> ShaderEffectCmdList::CreateFromData(const CmdListData& data, bool isCopy)
26 {
27 auto cmdList = std::make_shared<ShaderEffectCmdList>();
28 if (isCopy) {
29 cmdList->opAllocator_.BuildFromDataWithCopy(data.first, data.second);
30 } else {
31 cmdList->opAllocator_.BuildFromData(data.first, data.second);
32 }
33 return cmdList;
34 }
35
Playback() const36 std::shared_ptr<ShaderEffect> ShaderEffectCmdList::Playback() const
37 {
38 if (opAllocator_.GetSize() == 0) {
39 return nullptr;
40 }
41
42 uint32_t offset = 0;
43 std::shared_ptr<ShaderEffect> se = nullptr;
44 do {
45 OpItem* itemPtr = static_cast<OpItem*>(opAllocator_.OffsetToAddr(offset));
46 if (itemPtr != nullptr) {
47 switch (itemPtr->GetType()) {
48 case ShaderEffectOpItem::OPITEM_HEAD:
49 break;
50 case ShaderEffectOpItem::CREATE_COLOR_SHADER:
51 se = static_cast<CreateColorShaderOpItem*>(itemPtr)->Playback();
52 break;
53 case ShaderEffectOpItem::CREATE_BLEND_SHADER:
54 se = static_cast<CreateBlendShaderOpItem*>(itemPtr)->Playback(*this);
55 break;
56 case ShaderEffectOpItem::CREATE_IMAGE_SHADER:
57 se = static_cast<CreateImageShaderOpItem*>(itemPtr)->Playback(*this);
58 break;
59 case ShaderEffectOpItem::CREATE_PICTURE_SHADER:
60 se = static_cast<CreatePictureShaderOpItem*>(itemPtr)->Playback(*this);
61 break;
62 case ShaderEffectOpItem::CREATE_LINEAR_GRADIENT:
63 se = static_cast<CreateLinearGradientOpItem*>(itemPtr)->Playback(*this);
64 break;
65 case ShaderEffectOpItem::CREATE_RADIAL_GRADIENT:
66 se = static_cast<CreateRadialGradientOpItem*>(itemPtr)->Playback(*this);
67 break;
68 case ShaderEffectOpItem::CREATE_TWO_POINT_CONICAL:
69 se = static_cast<CreateTwoPointConicalOpItem*>(itemPtr)->Playback(*this);
70 break;
71 case ShaderEffectOpItem::CREATE_SWEEP_GRADIENT:
72 se = static_cast<CreateSweepGradientOpItem*>(itemPtr)->Playback(*this);
73 break;
74 default:
75 LOGE("ShaderEffectCmdList unknown OpItem type!");
76 break;
77 }
78 offset = itemPtr->GetNextOpItemOffset();
79 } else {
80 LOGE("ShaderEffectCmdList Playback failed!");
81 break;
82 }
83 } while (offset != 0);
84
85 return se;
86 }
87
88 /* OpItem */
CreateColorShaderOpItem(ColorQuad color)89 CreateColorShaderOpItem::CreateColorShaderOpItem(ColorQuad color)
90 : ShaderEffectOpItem(CREATE_COLOR_SHADER), color_(color) {}
91
Playback() const92 std::shared_ptr<ShaderEffect> CreateColorShaderOpItem::Playback() const
93 {
94 return ShaderEffect::CreateColorShader(color_);
95 }
96
CreateBlendShaderOpItem(const CmdListHandle & dst,const CmdListHandle & src,BlendMode mode)97 CreateBlendShaderOpItem::CreateBlendShaderOpItem(const CmdListHandle& dst, const CmdListHandle& src, BlendMode mode)
98 : ShaderEffectOpItem(CREATE_BLEND_SHADER), dst_(dst), src_(src), mode_(mode) {}
99
Playback(const CmdList & cmdList) const100 std::shared_ptr<ShaderEffect> CreateBlendShaderOpItem::Playback(const CmdList& cmdList) const
101 {
102 auto dst = CmdListHelper::GetFromCmdList<ShaderEffectCmdList, ShaderEffect>(cmdList, dst_);
103 auto src = CmdListHelper::GetFromCmdList<ShaderEffectCmdList, ShaderEffect>(cmdList, src_);
104 if (dst == nullptr || src == nullptr) {
105 LOGE("ShaderEffectCmdList Playback failed!");
106 return nullptr;
107 }
108
109 return ShaderEffect::CreateBlendShader(*dst, *src, mode_);
110 }
111
CreateImageShaderOpItem(const ImageHandle & image,TileMode tileX,TileMode tileY,const SamplingOptions & sampling,const Matrix & matrix)112 CreateImageShaderOpItem::CreateImageShaderOpItem(const ImageHandle& image, TileMode tileX, TileMode tileY,
113 const SamplingOptions& sampling, const Matrix& matrix) : ShaderEffectOpItem(CREATE_IMAGE_SHADER),
114 image_(image), tileX_(tileX), tileY_(tileY), samplingOptions_(sampling), matrix_(matrix) {}
115
Playback(const CmdList & cmdList) const116 std::shared_ptr<ShaderEffect> CreateImageShaderOpItem::Playback(const CmdList& cmdList) const
117 {
118 auto image = CmdListHelper::GetImageFromCmdList(cmdList, image_);
119 if (image == nullptr) {
120 return nullptr;
121 }
122
123 return ShaderEffect::CreateImageShader(*image, tileX_, tileY_, samplingOptions_, matrix_);
124 }
125
CreatePictureShaderOpItem(const ImageHandle & picture,TileMode tileX,TileMode tileY,FilterMode mode,const Matrix & matrix,const Rect & rect)126 CreatePictureShaderOpItem::CreatePictureShaderOpItem(const ImageHandle& picture, TileMode tileX, TileMode tileY,
127 FilterMode mode, const Matrix& matrix, const Rect& rect) : ShaderEffectOpItem(CREATE_PICTURE_SHADER),
128 picture_(picture), tileX_(tileX), tileY_(tileY), filterMode_(mode), matrix_(matrix), rect_(rect) {}
129
Playback(const CmdList & cmdList) const130 std::shared_ptr<ShaderEffect> CreatePictureShaderOpItem::Playback(const CmdList& cmdList) const
131 {
132 auto picture = CmdListHelper::GetPictureFromCmdList(cmdList, picture_);
133 if (picture == nullptr) {
134 return nullptr;
135 }
136
137 return ShaderEffect::CreatePictureShader(*picture, tileX_, tileY_, filterMode_, matrix_, rect_);
138 }
139
CreateLinearGradientOpItem(const Point & startPt,const Point & endPt,const std::pair<uint32_t,size_t> & colors,const std::pair<uint32_t,size_t> & pos,TileMode mode)140 CreateLinearGradientOpItem::CreateLinearGradientOpItem(const Point& startPt, const Point& endPt,
141 const std::pair<uint32_t, size_t>& colors, const std::pair<uint32_t, size_t>& pos, TileMode mode)
142 : ShaderEffectOpItem(CREATE_LINEAR_GRADIENT), startPt_(startPt), endPt_(endPt),
143 colors_(colors), pos_(pos), mode_(mode) {}
144
Playback(const CmdList & cmdList) const145 std::shared_ptr<ShaderEffect> CreateLinearGradientOpItem::Playback(const CmdList& cmdList) const
146 {
147 auto colors = CmdListHelper::GetVectorFromCmdList<ColorQuad>(cmdList, colors_);
148 auto pos = CmdListHelper::GetVectorFromCmdList<scalar>(cmdList, pos_);
149
150 return ShaderEffect::CreateLinearGradient(startPt_, endPt_, colors, pos, mode_);
151 }
152
CreateRadialGradientOpItem(const Point & centerPt,scalar radius,const std::pair<uint32_t,size_t> & colors,const std::pair<uint32_t,size_t> & pos,TileMode mode)153 CreateRadialGradientOpItem::CreateRadialGradientOpItem(const Point& centerPt, scalar radius,
154 const std::pair<uint32_t, size_t>& colors, const std::pair<uint32_t, size_t>& pos, TileMode mode)
155 : ShaderEffectOpItem(CREATE_RADIAL_GRADIENT), centerPt_(centerPt), radius_(radius),
156 colors_(colors), pos_(pos), mode_(mode) {}
157
Playback(const CmdList & cmdList) const158 std::shared_ptr<ShaderEffect> CreateRadialGradientOpItem::Playback(const CmdList& cmdList) const
159 {
160 auto colors = CmdListHelper::GetVectorFromCmdList<ColorQuad>(cmdList, colors_);
161 auto pos = CmdListHelper::GetVectorFromCmdList<scalar>(cmdList, pos_);
162
163 return ShaderEffect::CreateRadialGradient(centerPt_, radius_, colors, pos, mode_);
164 }
165
CreateTwoPointConicalOpItem(const Point & startPt,scalar startRadius,const Point & endPt,scalar endRadius,const std::pair<uint32_t,size_t> & colors,const std::pair<uint32_t,size_t> & pos,TileMode mode)166 CreateTwoPointConicalOpItem::CreateTwoPointConicalOpItem(const Point& startPt, scalar startRadius, const Point& endPt,
167 scalar endRadius, const std::pair<uint32_t, size_t>& colors, const std::pair<uint32_t, size_t>& pos, TileMode mode)
168 : ShaderEffectOpItem(CREATE_TWO_POINT_CONICAL), startPt_(startPt), startRadius_(startRadius), endPt_(endPt),
169 endRadius_(endRadius), colors_(colors), pos_(pos), mode_(mode) {}
170
Playback(const CmdList & cmdList) const171 std::shared_ptr<ShaderEffect> CreateTwoPointConicalOpItem::Playback(const CmdList& cmdList) const
172 {
173 auto colors = CmdListHelper::GetVectorFromCmdList<ColorQuad>(cmdList, colors_);
174 auto pos = CmdListHelper::GetVectorFromCmdList<scalar>(cmdList, pos_);
175
176 return ShaderEffect::CreateTwoPointConical(startPt_, startRadius_, endPt_, endRadius_, colors, pos, mode_);
177 }
178
CreateSweepGradientOpItem(const Point & centerPt,const std::pair<uint32_t,size_t> & colors,const std::pair<uint32_t,size_t> & pos,TileMode mode,scalar startAngle,scalar endAngle)179 CreateSweepGradientOpItem::CreateSweepGradientOpItem(const Point& centerPt, const std::pair<uint32_t, size_t>& colors,
180 const std::pair<uint32_t, size_t>& pos, TileMode mode, scalar startAngle, scalar endAngle)
181 : ShaderEffectOpItem(CREATE_SWEEP_GRADIENT), centerPt_(centerPt), colors_(colors),
182 pos_(pos), mode_(mode), startAngle_(startAngle), endAngle_(endAngle) {}
183
Playback(const CmdList & cmdList) const184 std::shared_ptr<ShaderEffect> CreateSweepGradientOpItem::Playback(const CmdList& cmdList) const
185 {
186 auto colors = CmdListHelper::GetVectorFromCmdList<ColorQuad>(cmdList, colors_);
187 auto pos = CmdListHelper::GetVectorFromCmdList<scalar>(cmdList, pos_);
188
189 return ShaderEffect::CreateSweepGradient(centerPt_, colors, pos, mode_, startAngle_, endAngle_);
190 }
191 } // namespace Drawing
192 } // namespace Rosen
193 } // namespace OHOS
194