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 "core/components/video/resource/ext_texture.h"
17 
18 #include "base/log/log.h"
19 #include "base/utils/utils.h"
20 
21 namespace OHOS::Ace {
22 const char TEXTURE_ERRORCODE_CREATEFAIL[] = "error_texture_000001";
23 const char TEXTURE_ERRORMSG_CREATEFAIL[] = "Unable to initialize texture.";
24 
25 const char TEXTURE_METHOD_REFRESH[] = "markTextureAvailable";
26 
27 const char SET_TEXTURE_SIZE[] = "setTextureSize";
28 const char TEXTURE_HEIGHT[] = "textureHeight";
29 const char TEXTURE_ID[] = "textureId";
30 const char IS_ATTACH[] = "isAttach";
31 const char TEXTURE_WIDTH[] = "textureWidth";
32 const char INSTANCE_ID[] = "instanceId";
33 const char ATTACH_TO_GLCONTEXT[] = "attachToGLContext";
34 const char UPDATE_TEXTURE_IMAGE[] = "updateTextureImage";
35 
~ExtTexture()36 ExtTexture::~ExtTexture()
37 {
38     auto context = context_.Upgrade();
39     CHECK_NULL_VOID(context);
40     auto resRegister = context->GetPlatformResRegister();
41     CHECK_NULL_VOID(resRegister);
42     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
43     if (platformTaskExecutor.IsRunOnCurrentThread()) {
44         resRegister->UnregisterEvent(MakeEventHash(TEXTURE_METHOD_REFRESH));
45     } else {
46         WeakPtr<PlatformResRegister> weak = resRegister;
47         platformTaskExecutor.PostTask([eventHash = MakeEventHash(TEXTURE_METHOD_REFRESH), weak] {
48             auto resRegister = weak.Upgrade();
49             CHECK_NULL_VOID(resRegister);
50             resRegister->UnregisterEvent(eventHash);
51         }, "ArkUIVideoExtTextureUnregisterEvent");
52     }
53 }
54 
Create(const std::function<void (int64_t)> & onCreate)55 void ExtTexture::Create(const std::function<void(int64_t)>& onCreate)
56 {
57     auto context = context_.Upgrade();
58     CHECK_NULL_VOID(context);
59 
60     auto platformTaskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::PLATFORM);
61     platformTaskExecutor.PostTask([weak = WeakClaim(this), onCreate] {
62         auto texture = weak.Upgrade();
63         if (texture) {
64             texture->CreateTexture(onCreate);
65         }
66     }, "ArkUIVideoCreateExtTexture");
67 }
68 
CreateTexture(const std::function<void (int64_t)> & onCreate)69 void ExtTexture::CreateTexture(const std::function<void(int64_t)>& onCreate)
70 {
71     auto context = context_.Upgrade();
72     CHECK_NULL_VOID(context);
73     auto resRegister = context->GetPlatformResRegister();
74     CHECK_NULL_VOID(resRegister);
75     id_ = resRegister->CreateResource(type_, PARAM_NONE);
76     if (id_ == INVALID_ID) {
77         if (onError_) {
78             onError_(TEXTURE_ERRORCODE_CREATEFAIL, TEXTURE_ERRORMSG_CREATEFAIL);
79         }
80         return;
81     }
82     hash_ = MakeResourceHash();
83     resRegister->RegisterEvent(
84         MakeEventHash(TEXTURE_METHOD_REFRESH), [weak = WeakClaim(this)](const std::string& param) {
85             auto texture = weak.Upgrade();
86             if (texture) {
87                 texture->OnRefresh(param);
88             }
89         });
90 
91     if (onCreate) {
92         onCreate(id_);
93     }
94     OnSurfaceCreated();
95 }
96 
SetSize(int64_t textureId,int32_t textureWidth,int32_t textureHeight)97 void ExtTexture::SetSize(int64_t textureId, int32_t textureWidth, int32_t textureHeight)
98 {
99     std::stringstream paramStream;
100     paramStream << TEXTURE_ID << PARAM_EQUALS << textureId << PARAM_AND
101                 << TEXTURE_WIDTH << PARAM_EQUALS << textureWidth << PARAM_AND
102                 << TEXTURE_HEIGHT << PARAM_EQUALS << textureHeight;
103     std::string param = paramStream.str();
104     CallResRegisterMethod(MakeMethodHash(SET_TEXTURE_SIZE), param);
105 }
106 
OnRefresh(const std::string & param)107 void ExtTexture::OnRefresh(const std::string& param)
108 {
109     instanceId_ = GetIntParam(param, INSTANCE_ID);
110     textureId_ = GetIntParam(param, TEXTURE_ID);
111     if (onTextureRefresh_) {
112         onTextureRefresh_(instanceId_, textureId_);
113     }
114 }
115 
OnSurfaceCreated()116 void ExtTexture::OnSurfaceCreated()
117 {
118     if (onSurfaceCreated_) {
119         onSurfaceCreated_();
120     }
121 }
122 
OnSurfaceChanged(int32_t width,int32_t height)123 void ExtTexture::OnSurfaceChanged(int32_t width, int32_t height)
124 {
125     LOGI("OnSurfaceChanged. width: %{public}d height: %{public}d", width, height);
126     if (onSurfaceChanged_) {
127         onSurfaceChanged_(width, height);
128     }
129 }
130 
AttachToGLContext(int64_t textureId,bool isAttach)131 void ExtTexture::AttachToGLContext(int64_t textureId, bool isAttach)
132 {
133     std::stringstream paramStream;
134     paramStream << TEXTURE_ID << PARAM_EQUALS << textureId << PARAM_AND
135         << IS_ATTACH << PARAM_EQUALS << (isAttach ? "1" : "0");
136     std::string param = paramStream.str();
137     CallSyncResRegisterMethod(MakeMethodHash(ATTACH_TO_GLCONTEXT), param);
138 }
139 
UpdateTextureImage(std::vector<float> & matrix)140 void ExtTexture::UpdateTextureImage(std::vector<float>& matrix)
141 {
142     CallSyncResRegisterMethod(MakeMethodHash(UPDATE_TEXTURE_IMAGE), PARAM_NONE,
143         [this, &matrix](std::string& result) mutable {
144             GetFloatArrayParam(result, "transform", matrix);
145     });
146 }
147 } // namespace OHOS::Ace