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