• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "property/rs_color_picker_cache_task.h"
17 
18 #include <atomic>
19 
20 #ifndef USE_ROSEN_DRAWING
21 #include "include/gpu/GrBackendSurface.h"
22 #include "src/image/SkImage_Base.h"
23 #else
24 #include "effect/runtime_effect.h"
25 #include "effect/runtime_shader_builder.h"
26 #endif
27 
28 #if defined(NEW_SKIA)
29 #include "include/gpu/GrDirectContext.h"
30 #else
31 #include "include/gpu/GrContext.h"
32 #endif
33 
34 #include "common/rs_optional_trace.h"
35 #include "platform/common/rs_log.h"
36 #include "platform/common/rs_system_properties.h"
37 
38 namespace OHOS {
39 namespace Rosen {
40 #define CHECK_CACHE_PROCESS_STATUS                                       \
41     do {                                                                 \
42         if (cacheProcessStatus_.load() == CacheProcessStatus::WAITING) { \
43             return false;                                                \
44         }                                                                \
45     } while (false)
46 
47 const bool RSColorPickerCacheTask::ColorPickerPartialEnabled =
48     RSSystemProperties::GetColorPickerPartialEnabled() && RSUniRenderJudgement::IsUniRender();
49 
50 #ifndef USE_ROSEN_DRAWING
InitSurface(GrRecordingContext * grContext)51 bool RSColorPickerCacheTask::InitSurface(GrRecordingContext* grContext)
52 #else
53 bool RSColorPickerCacheTask::InitSurface(Drawing::GPUContext* gpuContext)
54 #endif
55 {
56     RS_TRACE_NAME("RSColorPickerCacheTask InitSurface");
57     if (cacheSurface_ != nullptr) {
58         return true;
59     }
60 #ifdef IS_OHOS
61     auto runner = AppExecFwk::EventRunner::Current();
62     handler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
63 #endif
64 #ifndef USE_ROSEN_DRAWING
65     SkImageInfo info = SkImageInfo::MakeN32Premul(surfaceSize_.width(), surfaceSize_.height());
66     cacheSurface_ = SkSurface::MakeRenderTarget(grContext, SkBudgeted::kYes, info);
67 #else
68     Drawing::ImageInfo info = Drawing::ImageInfo::MakeN32Premul(surfaceSize_.GetWidth(), surfaceSize_.GetHeight());
69     cacheSurface_ = Drawing::Surface::MakeRenderTarget(gpuContext, true, info);
70 #endif
71 
72     return cacheSurface_ != nullptr;
73 }
74 
75 #ifndef USE_ROSEN_DRAWING
InitTask(const sk_sp<SkImage> imageSnapshot)76 bool RSColorPickerCacheTask::InitTask(const sk_sp<SkImage> imageSnapshot)
77 #else
78 bool RSColorPickerCacheTask::InitTask(const std::shared_ptr<Drawing::Image> imageSnapshot)
79 #endif
80 {
81     if (imageSnapshot == nullptr) {
82         ROSEN_LOGE("RSColorPickerCacheTask imageSnapshot is null");
83         return false;
84     }
85     if (imageSnapshotCache_) {
86 #ifndef USE_ROSEN_DRAWING
87         cacheBackendTexture_ = imageSnapshotCache_->getBackendTexture(false);
88 #else
89         cacheBackendTexture_ = imageSnapshotCache_->GetBackendTexture(false, nullptr);
90 #endif
91         return true;
92     }
93     ROSEN_LOGD("RSColorPickerCacheTask InitTask:%{public}p", this);
94 #ifdef IS_OHOS
95     auto runner = AppExecFwk::EventRunner::Current();
96     initHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
97 #endif
98     imageSnapshotCache_ = imageSnapshot;
99 #ifndef USE_ROSEN_DRAWING
100     surfaceSize_.set(imageSnapshotCache_->width(), imageSnapshotCache_->height());
101 #else
102     surfaceSize_.SetRight(imageSnapshotCache_->GetWidth());
103     surfaceSize_.SetBottom(imageSnapshotCache_->GetHeight());
104 #endif
105     return false;
106 }
107 
Reset()108 void RSColorPickerCacheTask::Reset()
109 {
110     ROSEN_LOGD("RSColorPickerCacheTask::Reset:%{public}p", this);
111     {
112         std::unique_lock<std::mutex> lock(*grBackendTextureMutex_);
113         if (!imageSnapshotCache_) {
114             return;
115         }
116         imageSnapshotCache_.reset();
117         waitRelease_->store(false);
118     }
119 }
120 
121 #ifndef USE_ROSEN_DRAWING
GpuScaleImage(std::shared_ptr<RSPaintFilterCanvas> cacheCanvas,const sk_sp<SkImage> threadImage,std::shared_ptr<SkPixmap> & dst)122 bool RSColorPickerCacheTask::GpuScaleImage(std::shared_ptr<RSPaintFilterCanvas> cacheCanvas,
123     const sk_sp<SkImage> threadImage, std::shared_ptr<SkPixmap>& dst)
124 {
125     if (cacheCanvas == nullptr) {
126         SetStatus(CacheProcessStatus::WAITING);
127         ROSEN_LOGE("RSColorPickerCacheTask cacheCanvas is null");
128         return false;
129     }
130     SkString shaderString(R"(
131         uniform shader imageInput;
132 
133         half4 main(float2 xy) {
134             half4 c = imageInput.eval(xy);
135             return half4(c.rgb, 1.0);
136         }
137     )");
138 
139     auto [effect, error] = SkRuntimeEffect::MakeForShader(shaderString);
140     if (!effect) {
141         ROSEN_LOGE("RSColorPickerCacheTask effect is null");
142         SetStatus(CacheProcessStatus::WAITING);
143         return false;
144     }
145 
146     SkSamplingOptions linear(SkFilterMode::kLinear, SkMipmapMode::kNone);
147     SkRuntimeShaderBuilder effectBulider(effect);
148     SkImageInfo pcInfo;
149     SkMatrix matrix;
150     if (threadImage->width() * threadImage->height() < 10000) { // 10000 = 100 * 100 pixels
151         pcInfo = SkImageInfo::MakeN32Premul(10, 10); // 10 * 10 pixels
152         matrix = SkMatrix::Scale(10.0 / threadImage->width(), 10.0 / threadImage->height()); // 10.0 pixels
153     } else {
154         pcInfo = SkImageInfo::MakeN32Premul(100, 100); // 100 * 100 pixels
155         matrix = SkMatrix::Scale(100.0 / threadImage->width(), 100.0 / threadImage->height());  // 100.0 pixels
156     }
157     effectBulider.child("imageInput") = threadImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp, linear, matrix);
158     sk_sp<SkImage> tmpColorImg = effectBulider.makeImage(cacheCanvas->recordingContext(), nullptr, pcInfo, false);
159 
160     const int buffLen = tmpColorImg->width() * tmpColorImg->height();
161     if (pixelPtr_ != nullptr) {
162         delete [] pixelPtr_;
163         pixelPtr_ = nullptr;
164     }
165     pixelPtr_ = new uint32_t[buffLen];
166 
167     auto info = tmpColorImg->imageInfo();
168     dst = std::make_shared<SkPixmap>(info, pixelPtr_, info.width() * info.bytesPerPixel());
169     bool flag = tmpColorImg->readPixels(*dst, 0, 0);
170 
171     return flag;
172 }
173 #else
GpuScaleImage(std::shared_ptr<RSPaintFilterCanvas> cacheCanvas,const std::shared_ptr<Drawing::Image> threadImage,std::shared_ptr<Drawing::Pixmap> & dst)174 bool RSColorPickerCacheTask::GpuScaleImage(std::shared_ptr<RSPaintFilterCanvas> cacheCanvas,
175     const std::shared_ptr<Drawing::Image> threadImage, std::shared_ptr<Drawing::Pixmap>& dst)
176 {
177     if (cacheCanvas == nullptr) {
178         SetStatus(CacheProcessStatus::WAITING);
179         ROSEN_LOGE("RSColorPickerCacheTask cacheCanvas is null");
180         return false;
181     }
182     std::string shaderString(R"(
183         uniform shader imageInput;
184 
185         half4 main(float2 xy) {
186             half4 c = imageInput.eval(xy);
187             return half4(c.rgb, 1.0);
188         }
189     )");
190 
191     std::shared_ptr<Drawing::RuntimeEffect> effect = Drawing::RuntimeEffect::CreateForShader(shaderString);
192     if (!effect) {
193         ROSEN_LOGE("RSColorPickerCacheTask effect is null");
194         SetStatus(CacheProcessStatus::WAITING);
195         return false;
196     }
197 
198     Drawing::SamplingOptions linear(Drawing::FilterMode::LINEAR, Drawing::MipmapMode::NONE);
199     std::shared_ptr<Drawing::RuntimeShaderBuilder> effectBulider =
200         std::make_shared<Drawing::RuntimeShaderBuilder>(effect);
201     Drawing::ImageInfo pcInfo;
202     Drawing::Matrix matrix;
203     matrix.SetScale(1.0, 1.0);
204     if (threadImage->GetWidth() * threadImage->GetHeight() < 10000) { // 10000 = 100 * 100 pixels
205         pcInfo = Drawing::ImageInfo::MakeN32Premul(10, 10); // 10 * 10 pixels
206         matrix.SetScale(10.0 / threadImage->GetWidth(), 10.0 / threadImage->GetHeight()); // 10.0 pixels
207     } else {
208         pcInfo = Drawing::ImageInfo::MakeN32Premul(100, 100); // 100 * 100 pixels
209         matrix.SetScale(100.0 / threadImage->GetWidth(), 100.0 / threadImage->GetHeight());  // 100.0 pixels
210     }
211     effectBulider->SetChild("imageInput", Drawing::ShaderEffect::CreateImageShader(
212         *threadImage, Drawing::TileMode::CLAMP, Drawing::TileMode::CLAMP, linear, matrix));
213     std::shared_ptr<Drawing::Image> tmpColorImg = effectBulider->MakeImage(
214         cacheCanvas->GetGPUContext().get(), nullptr, pcInfo, false);
215 
216     const int buffLen = tmpColorImg->GetWidth() * tmpColorImg->GetHeight();
217     if (pixelPtr_ != nullptr) {
218         delete [] pixelPtr_;
219         pixelPtr_ = nullptr;
220     }
221     pixelPtr_ = new uint32_t[buffLen];
222 
223     auto info = tmpColorImg->GetImageInfo();
224     dst = std::make_shared<Drawing::Pixmap>(info, pixelPtr_, info.GetWidth() * info.GetBytesPerPixel());
225     bool flag = tmpColorImg->ReadPixels(*dst, 0, 0);
226 
227     return flag;
228 }
229 #endif
230 
231 #ifndef USE_ROSEN_DRAWING
Render()232 bool RSColorPickerCacheTask::Render()
233 {
234     RS_TRACE_NAME_FMT("RSColorPickerCacheTask::Render:%p", this);
235     if (cacheSurface_ == nullptr) {
236         SetStatus(CacheProcessStatus::WAITING);
237         ROSEN_LOGE("RSColorPickerCacheTask cacheSurface is null");
238         return false;
239     }
240     CHECK_CACHE_PROCESS_STATUS;
241     std::shared_ptr<RSPaintFilterCanvas> cacheCanvas = std::make_shared<RSPaintFilterCanvas>(cacheSurface_.get());
242     if (cacheCanvas == nullptr) {
243         SetStatus(CacheProcessStatus::WAITING);
244         ROSEN_LOGE("RSColorPickerCacheTask cacheCanvas is null");
245         return false;
246     }
247 
248     auto threadImage = SkImage::MakeFromTexture(cacheCanvas->recordingContext(), cacheBackendTexture_,
249         kBottomLeft_GrSurfaceOrigin, kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr);
250 
251     SkColor color;
252     std::shared_ptr<SkPixmap> dst;
253     if (GpuScaleImage(cacheCanvas, threadImage, dst)) {
254         uint32_t errorCode = 0;
255         std::shared_ptr<RSColorPicker> colorPicker = RSColorPicker::CreateColorPicker(dst, errorCode);
256         if (errorCode == 0) {
257             if (isShadow_ && shadowColorStrategy_ == SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN) {
258                 colorPicker->GetLargestProportionColor(color);
259             } else {
260                 colorPicker->GetAverageColor(color);
261             }
262             std::unique_lock<std::mutex> lock(colorMutex_);
263             color_ = RSColor(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), SkColorGetA(color));
264             firstGetColorFinished_ = true;
265             valid_ = true;
266         } else {
267             valid_ = false;
268         }
269     } else {
270         valid_ = false;
271     }
272     if (pixelPtr_ != nullptr) {
273         delete [] pixelPtr_;
274         pixelPtr_ = nullptr;
275     }
276 
277     CHECK_CACHE_PROCESS_STATUS;
278     std::unique_lock<std::mutex> lock(parallelRenderMutex_);
279     cacheProcessStatus_.store(CacheProcessStatus::DONE);
280     Notify();
281     return true;
282 }
283 #else
Render()284 bool RSColorPickerCacheTask::Render()
285 {
286     RS_TRACE_NAME_FMT("RSColorPickerCacheTask::Render:%p", this);
287     ROSEN_LOGD("RSColorPickerCacheTask::Render:%{public}p", this);
288     if (cacheSurface_ == nullptr) {
289         SetStatus(CacheProcessStatus::WAITING);
290         ROSEN_LOGE("RSColorPickerCacheTask cacheSurface is null");
291         return false;
292     }
293     CHECK_CACHE_PROCESS_STATUS;
294     std::shared_ptr<RSPaintFilterCanvas> cacheCanvas = std::make_shared<RSPaintFilterCanvas>(cacheSurface_.get());
295     CHECK_CACHE_PROCESS_STATUS;
296     auto threadImage = std::make_shared<Drawing::Image>();
297     Drawing::BitmapFormat info = Drawing::BitmapFormat { Drawing::COLORTYPE_RGBA_8888,
298         Drawing::ALPHATYPE_PREMUL };
299     {
300         std::unique_lock<std::mutex> lock(*grBackendTextureMutex_);
301         if (cacheCanvas == nullptr || !cacheBackendTexture_.IsValid()) {
302             SetStatus(CacheProcessStatus::WAITING);
303             ROSEN_LOGE("RSColorPickerCacheTask cacheCanvas is null or cacheBackendTexture not valid");
304             return false;
305         }
306         if (!threadImage->BuildFromTexture(*cacheCanvas->GetGPUContext(), cacheBackendTexture_.GetTextureInfo(),
307             Drawing::TextureOrigin::BOTTOM_LEFT, info, nullptr)) {
308             SetStatus(CacheProcessStatus::WAITING);
309             ROSEN_LOGE("RSColorPickerCacheTask::Render BuildFromTexture failed");
310             return false;
311         }
312     }
313     CHECK_CACHE_PROCESS_STATUS;
314     Drawing::ColorQuad color;
315     std::shared_ptr<Drawing::Pixmap> dst;
316     if (GpuScaleImage(cacheCanvas, threadImage, dst)) {
317         uint32_t errorCode = 0;
318         CHECK_CACHE_PROCESS_STATUS;
319         std::shared_ptr<RSColorPicker> colorPicker = RSColorPicker::CreateColorPicker(dst, errorCode);
320         if (errorCode == 0) {
321             if (isShadow_ && shadowColorStrategy_ == SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN) {
322                 colorPicker->GetLargestProportionColor(color);
323             } else {
324                 colorPicker->GetAverageColor(color);
325             }
326             std::unique_lock<std::mutex> lock(colorMutex_);
327             color_ = RSColor(Drawing::Color::ColorQuadGetR(color), Drawing::Color::ColorQuadGetG(color),
328                 Drawing::Color::ColorQuadGetB(color), Drawing::Color::ColorQuadGetA(color));
329             firstGetColorFinished_ = true;
330             valid_ = true;
331         } else {
332             valid_ = false;
333         }
334     } else {
335         valid_ = false;
336     }
337     if (pixelPtr_ != nullptr) {
338         delete [] pixelPtr_;
339         pixelPtr_ = nullptr;
340     }
341 
342     CHECK_CACHE_PROCESS_STATUS;
343     std::unique_lock<std::mutex> lock(parallelRenderMutex_);
344     cacheProcessStatus_.store(CacheProcessStatus::DONE);
345     Notify();
346     return true;
347 }
348 #endif
349 
GetColor(RSColor & color)350 bool RSColorPickerCacheTask::GetColor(RSColor& color)
351 {
352     std::unique_lock<std::mutex> lock(colorMutex_);
353     color = color_;
354     return valid_;
355 }
356 
CalculateColorAverage(RSColor & colorCur)357 void RSColorPickerCacheTask::CalculateColorAverage(RSColor& colorCur)
358 {
359     // black color defination
360     RSColor black = RSColor(0, 0, 0, 255);
361     int colorArrayLen = colorArray_.size();
362     int colorArraySize = 20;
363     int continueBlackColorNum = 5;
364     if (colorArrayLen >= colorArraySize) {
365         colorArray_.pop_back();
366     }
367     colorArray_.emplace(colorArray_.begin(), colorCur);
368     int validColorNum = 0;
369     int R = 0;
370     int G = 0;
371     int B = 0;
372     int mark = 0;
373 
374     for (int i = 0; i < static_cast<int>(colorArray_.size()); i++) {
375         if (colorArray_[i].GetRed() == 0 && colorArray_[i].GetGreen() == 0 && colorArray_[i].GetBlue() == 0) {
376             ++mark;
377         } else {
378             if (mark > continueBlackColorNum) {
379                 R += black.GetRed() * mark;
380                 G += black.GetGreen() * mark;
381                 B += black.GetBlue() * mark;
382                 validColorNum += mark;
383             }
384             R += colorArray_[i].GetRed();
385             G += colorArray_[i].GetGreen();
386             B += colorArray_[i].GetBlue();
387             validColorNum++;
388             mark = 0;
389         }
390     }
391 
392     if (mark > continueBlackColorNum) {
393         R += black.GetRed() * mark;
394         G += black.GetGreen() * mark;
395         B += black.GetBlue() * mark;
396         validColorNum += mark;
397     }
398 
399     if (validColorNum != 0) {
400         R = R / validColorNum;
401         G = G / validColorNum;
402         B = B / validColorNum;
403     } else {
404         colorAverage_ = colorCur;
405     }
406 
407     colorAverage_ = RSColor(R, G, B, colorCur.GetAlpha());
408 }
409 
GetColorAverage(RSColor & color)410 void RSColorPickerCacheTask::GetColorAverage(RSColor& color)
411 {
412     std::unique_lock<std::mutex> lock(parallelRenderMutex_);
413     CalculateColorAverage(color_);
414     color = colorAverage_;
415 }
416 
GetFirstGetColorFinished()417 bool RSColorPickerCacheTask::GetFirstGetColorFinished()
418 {
419     return firstGetColorFinished_;
420 }
421 
422 std::function<void(std::weak_ptr<RSColorPickerCacheTask>)> RSColorPickerCacheTask::postColorPickerTask = nullptr;
423 #ifdef IS_OHOS
424     std::function<void(std::shared_ptr<Drawing::Image> &&,
425         std::shared_ptr<Drawing::Surface> &&,
426         std::shared_ptr<OHOS::AppExecFwk::EventHandler>,
427         std::weak_ptr<std::atomic<bool>>,
428         std::weak_ptr<std::mutex>)> RSColorPickerCacheTask::saveImgAndSurToRelease = nullptr;
429 #endif
430 
431 #ifndef USE_ROSEN_DRAWING
PostPartialColorPickerTask(std::shared_ptr<RSColorPickerCacheTask> colorPickerTask,sk_sp<SkImage> imageSnapshot)432 bool RSColorPickerCacheTask::PostPartialColorPickerTask(std::shared_ptr<RSColorPickerCacheTask> colorPickerTask,
433     sk_sp<SkImage> imageSnapshot)
434 #else
435 bool RSColorPickerCacheTask::PostPartialColorPickerTask(std::shared_ptr<RSColorPickerCacheTask> colorPickerTask,
436     std::shared_ptr<Drawing::Image> imageSnapshot)
437 #endif
438 {
439     ROSEN_LOGD("RSColorPickerCacheTask::PostPartialColorPickerTask:%{public}p", colorPickerTask.get());
440     if (RSColorPickerCacheTask::postColorPickerTask == nullptr) {
441         ROSEN_LOGD("PostPartialColorPickerTask::postColorPickerTask is null\n");
442         return false;
443     }
444 
445     if (colorPickerTask == nullptr) {
446         ROSEN_LOGE("PostPartialColorPickerTask::colorPickerTask is null\n");
447         return false;
448     }
449 
450     if (imageSnapshot == nullptr) {
451         ROSEN_LOGE("PostPartialColorPickerTask::colorPickerTask is null\n");
452         return false;
453     }
454 
455     if (colorPickerTask->GetStatus() == CacheProcessStatus::WAITING && !colorPickerTask->GetWaitRelease()) {
456         if (colorPickerTask->InitTask(imageSnapshot)) {
457             ROSEN_LOGD("PostPartialColorPickerTask, init task");
458             colorPickerTask->SetStatus(CacheProcessStatus::DOING);
459             RSColorPickerCacheTask::postColorPickerTask(colorPickerTask);
460         }
461         return false;
462     } else if (colorPickerTask->GetStatus() == CacheProcessStatus::DONE) {
463         ROSEN_LOGD("PostPartialColorPickerTask, DONE");
464         #ifdef IS_OHOS
465             colorPickerTask->SetWaitRelease(true);
466             auto initHandler = colorPickerTask->GetInitHandler();
467             if (initHandler != nullptr) {
468                 auto task = colorPickerTask;
469                 ROSEN_LOGD("CacheProcessStatus::DONE, Reset():%{public}p", task.get());
470                 initHandler->PostTask(
471                     [task]() { task->Reset(); }, AppExecFwk::EventQueue::Priority::IMMEDIATE);
472             }
473         #endif
474         return true;
475     } else {
476         ROSEN_LOGD("PostPartialColorPickerTask, doing or wait release");
477         return false;
478     }
479 }
480 
SetDeviceSize(int & deviceWidth,int & deviceHeight)481 void RSColorPickerCacheTask::SetDeviceSize(int& deviceWidth, int& deviceHeight)
482 {
483     deviceWidth_ = deviceWidth;
484     deviceHeight_ = deviceHeight;
485 }
486 
SetIsShadow(bool isShadow)487 void RSColorPickerCacheTask::SetIsShadow(bool isShadow)
488 {
489     isShadow_ = isShadow;
490 }
491 
SetShadowColorStrategy(int shadowColorStrategy)492 void RSColorPickerCacheTask::SetShadowColorStrategy(int shadowColorStrategy)
493 {
494     shadowColorStrategy_ = shadowColorStrategy;
495 }
496 
SetWaitRelease(bool waitRelease)497 void RSColorPickerCacheTask::SetWaitRelease(bool waitRelease)
498 {
499     waitRelease_->store(waitRelease);
500 }
501 
GetDeviceSize(int & deviceWidth,int & deviceHeight) const502 bool RSColorPickerCacheTask::GetDeviceSize(int& deviceWidth, int& deviceHeight) const
503 {
504     if (deviceWidth_.has_value() && deviceHeight_.has_value()) {
505         deviceWidth = deviceWidth_.value();
506         deviceHeight = deviceHeight_.value();
507         return true;
508     }
509     return false;
510 }
511 
GetWaitRelease() const512 bool RSColorPickerCacheTask::GetWaitRelease() const
513 {
514     return waitRelease_->load();
515 }
516 
ReleaseColorPicker()517 void RSColorPickerCacheTask::ReleaseColorPicker()
518 {
519 #ifdef IS_OHOS
520     waitRelease_->store(true);
521     cacheProcessStatus_.store(CacheProcessStatus::WAITING);
522     if (imageSnapshotCache_ || cacheSurface_ || initHandler_ || handler_) {
523         ROSEN_LOGD("RSColorPickerCacheTask::ReleaseColorPicker:%{public}p", this);
524         RSColorPickerCacheTask::saveImgAndSurToRelease(std::move(imageSnapshotCache_), std::move(cacheSurface_),
525             initHandler_, waitRelease_, grBackendTextureMutex_);
526     }
527 #endif
528 }
529 
530 } // namespace Rosen
531 } // namespace OHOS
532 
533