1 /*
2  * Copyright (c) 2024 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 "drawing_surface.h"
17 
18 #include <mutex>
19 #include <unordered_map>
20 
21 #include "drawing_canvas_utils.h"
22 
23 #include "draw/surface.h"
24 #include "image/gpu_context.h"
25 #include "image/image_info.h"
26 
27 using namespace OHOS;
28 using namespace Rosen;
29 using namespace Drawing;
30 
31 static std::mutex g_surfaceMutex;
32 static std::unordered_map<void*, std::shared_ptr<Surface>> g_surfaceMap;
33 
CastToSurface(OH_Drawing_Surface * cSurface)34 static Surface* CastToSurface(OH_Drawing_Surface* cSurface)
35 {
36     return reinterpret_cast<Surface*>(cSurface);
37 }
38 
CastToGpuContext(OH_Drawing_GpuContext * cGpuContext)39 static GPUContext* CastToGpuContext(OH_Drawing_GpuContext* cGpuContext)
40 {
41     return reinterpret_cast<GPUContext*>(cGpuContext);
42 }
43 
OH_Drawing_SurfaceCreateFromGpuContext(OH_Drawing_GpuContext * cGpuContext,bool budgeted,OH_Drawing_Image_Info cImageInfo)44 OH_Drawing_Surface* OH_Drawing_SurfaceCreateFromGpuContext(OH_Drawing_GpuContext* cGpuContext,
45     bool budgeted, OH_Drawing_Image_Info cImageInfo)
46 {
47     if (cGpuContext == nullptr) {
48         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
49         return nullptr;
50     }
51     ImageInfo imageInfo(cImageInfo.width, cImageInfo.height,
52         static_cast<ColorType>(cImageInfo.colorType), static_cast<AlphaType>(cImageInfo.alphaType));
53     std::shared_ptr<Surface> surface = Surface::MakeRenderTarget(CastToGpuContext(cGpuContext),
54         budgeted, imageInfo);
55     if (surface == nullptr) {
56         return nullptr;
57     }
58     std::lock_guard<std::mutex> lock(g_surfaceMutex);
59     g_surfaceMap.insert({surface.get(), surface});
60     return (OH_Drawing_Surface*)(surface.get());
61 }
62 
OH_Drawing_SurfaceGetCanvas(OH_Drawing_Surface * cSurface)63 OH_Drawing_Canvas* OH_Drawing_SurfaceGetCanvas(OH_Drawing_Surface* cSurface)
64 {
65     Surface* surface = CastToSurface(cSurface);
66     if (surface == nullptr) {
67         g_drawingErrorCode = OH_DRAWING_ERROR_INVALID_PARAMETER;
68         return nullptr;
69     }
70     return (OH_Drawing_Canvas*)(surface->GetCanvas().get());
71 }
72 
OH_Drawing_SurfaceDestroy(OH_Drawing_Surface * cSurface)73 void OH_Drawing_SurfaceDestroy(OH_Drawing_Surface* cSurface)
74 {
75     if (cSurface == nullptr) {
76         return;
77     }
78     std::lock_guard<std::mutex> lock(g_surfaceMutex);
79     auto it = g_surfaceMap.find(cSurface);
80     if (it == g_surfaceMap.end()) {
81         return;
82     }
83     g_surfaceMap.erase(it);
84 }
85