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 "glfw_render_context.h" 17 18 #include <mutex> 19 20 #include <GLFW/glfw3.h> 21 22 #include "hilog/log.h" 23 24 namespace OHOS::Rosen { 25 namespace { 26 constexpr ::OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, 0xD001403, "GlfwRC" }; 27 } 28 GetGlobal()29 std::shared_ptr<GlfwRenderContext> GlfwRenderContext::GetGlobal() 30 { 31 if (global_ == nullptr) { 32 static std::mutex mutex; 33 std::lock_guard lock(mutex); 34 if (global_ == nullptr) { 35 global_ = std::make_shared<GlfwRenderContext>(); 36 } 37 } 38 39 return global_; 40 } 41 Init()42 int GlfwRenderContext::Init() 43 { 44 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "Init"); 45 external_ = false; 46 int flag = glfwInit(); 47 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "Init end"); 48 return flag; 49 } 50 InitFrom(void * glfwWindow)51 void GlfwRenderContext::InitFrom(void *glfwWindow) 52 { 53 if (glfwWindow == nullptr) { 54 ::OHOS::HiviewDFX::HiLog::Error(LABEL, "InitFrom glfwWindow is nullptr"); 55 return; 56 } 57 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "InitFrom glfwWindow"); 58 59 external_ = true; 60 61 // to be done: replace this with normal way, a no flutter way. 62 // from third_party/flutter/engine/flutter/shell/platform/glfw/flutter_glfw.cc +39 63 window_ = *reinterpret_cast<GLFWwindow **>(glfwWindow); 64 65 glfwSetCharCallback(window_, nullptr); 66 glfwSetCursorEnterCallback(window_, nullptr); 67 glfwSetCursorPosCallback(window_, nullptr); 68 glfwSetFramebufferSizeCallback(window_, nullptr); 69 glfwSetKeyCallback(window_, nullptr); 70 glfwSetMouseButtonCallback(window_, nullptr); 71 glfwSetScrollCallback(window_, nullptr); 72 glfwSetWindowRefreshCallback(window_, nullptr); 73 glfwSetWindowUserPointer(window_, this); 74 75 glfwGetWindowSize(window_, &width_, &height_); 76 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "glfwSetWindowSizeCallback %{public}d %{public}d", width_, height_); 77 glfwSetWindowSizeCallback(window_, GlfwRenderContext::OnSizeChanged); 78 } 79 Terminate()80 void GlfwRenderContext::Terminate() 81 { 82 if (external_) { 83 return; 84 } 85 86 glfwTerminate(); 87 } 88 CreateGlfwWindow(int32_t width,int32_t height,bool visible)89 int GlfwRenderContext::CreateGlfwWindow(int32_t width, int32_t height, bool visible) 90 { 91 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "CreateGlfwWindow"); 92 if (external_) { 93 return 0; 94 } 95 96 if (window_ != nullptr) { 97 return 0; 98 } 99 100 auto flag = visible ? GLFW_TRUE : GLFW_FALSE; 101 glfwWindowHint(GLFW_DECORATED, flag); 102 glfwWindowHint(GLFW_VISIBLE, flag); 103 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "CreateGlfwWindow::glfwWindowHint end"); 104 window_ = glfwCreateWindow(width, height, "glfw window", nullptr, nullptr); 105 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "CreateGlfwWindow::glfwCreateWindow end"); 106 if (window_ == nullptr) { 107 return 1; 108 } 109 110 glfwSetWindowUserPointer(window_, this); 111 112 width_ = width; 113 height_ = height; 114 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "glfwSetWindowSizeCallback %{public}d %{public}d", width, height); 115 glfwSetWindowSizeCallback(window_, GlfwRenderContext::OnSizeChanged); 116 return 0; 117 } 118 DestroyWindow()119 void GlfwRenderContext::DestroyWindow() 120 { 121 if (external_) { 122 return; 123 } 124 125 if (window_ != nullptr) { 126 glfwDestroyWindow(window_); 127 } 128 } 129 WindowShouldClose()130 int GlfwRenderContext::WindowShouldClose() 131 { 132 return glfwWindowShouldClose(window_); 133 } 134 WaitForEvents()135 void GlfwRenderContext::WaitForEvents() 136 { 137 glfwWaitEvents(); 138 } 139 PollEvents()140 void GlfwRenderContext::PollEvents() 141 { 142 glfwPollEvents(); 143 } 144 GetWindowSize(int32_t & width,int32_t & height)145 void GlfwRenderContext::GetWindowSize(int32_t &width, int32_t &height) 146 { 147 glfwGetWindowSize(window_, &width, &height); 148 } 149 SetWindowSize(int32_t width,int32_t height)150 void GlfwRenderContext::SetWindowSize(int32_t width, int32_t height) 151 { 152 width_ = width; 153 height_ = height; 154 glfwSetWindowSize(window_, width, height); 155 } 156 SetWindowTitle(const std::string & title)157 void GlfwRenderContext::SetWindowTitle(const std::string &title) 158 { 159 glfwSetWindowTitle(window_, title.c_str()); 160 } 161 GetClipboardData()162 std::string GlfwRenderContext::GetClipboardData() 163 { 164 return glfwGetClipboardString(window_); 165 } 166 SetClipboardData(const std::string & data)167 void GlfwRenderContext::SetClipboardData(const std::string &data) 168 { 169 glfwSetClipboardString(window_, data.c_str()); 170 } 171 MakeCurrent()172 void GlfwRenderContext::MakeCurrent() 173 { 174 glfwMakeContextCurrent(window_); 175 } 176 SwapBuffers()177 void GlfwRenderContext::SwapBuffers() 178 { 179 glfwSwapBuffers(window_); 180 } 181 OnMouseButton(const OnMouseButtonFunc & onMouseBotton)182 void GlfwRenderContext::OnMouseButton(const OnMouseButtonFunc &onMouseBotton) 183 { 184 onMouseBotton_ = onMouseBotton; 185 glfwSetMouseButtonCallback(window_, GlfwRenderContext::OnMouseButton); 186 } 187 OnCursorPos(const OnCursorPosFunc & onCursorPos)188 void GlfwRenderContext::OnCursorPos(const OnCursorPosFunc &onCursorPos) 189 { 190 onCursorPos_ = onCursorPos; 191 glfwSetCursorPosCallback(window_, GlfwRenderContext::OnCursorPos); 192 } 193 OnKey(const OnKeyFunc & onKey)194 void GlfwRenderContext::OnKey(const OnKeyFunc &onKey) 195 { 196 onKey_ = onKey; 197 glfwSetKeyCallback(window_, GlfwRenderContext::OnKey); 198 } 199 OnChar(const OnCharFunc & onChar)200 void GlfwRenderContext::OnChar(const OnCharFunc &onChar) 201 { 202 onChar_ = onChar; 203 glfwSetCharCallback(window_, GlfwRenderContext::OnChar); 204 } 205 OnSizeChanged(const OnSizeChangedFunc & onSizeChanged)206 void GlfwRenderContext::OnSizeChanged(const OnSizeChangedFunc &onSizeChanged) 207 { 208 onSizeChanged_ = onSizeChanged; 209 glfwSetWindowSizeCallback(window_, GlfwRenderContext::OnSizeChanged); 210 } 211 OnMouseButton(GLFWwindow * window,int button,int action,int mods)212 void GlfwRenderContext::OnMouseButton(GLFWwindow *window, int button, int action, int mods) 213 { 214 const auto &that = reinterpret_cast<GlfwRenderContext *>(glfwGetWindowUserPointer(window)); 215 if (that->onMouseBotton_) { 216 that->onMouseBotton_(button, action == GLFW_PRESS, mods); 217 } 218 } 219 OnCursorPos(GLFWwindow * window,double x,double y)220 void GlfwRenderContext::OnCursorPos(GLFWwindow *window, double x, double y) 221 { 222 const auto &that = reinterpret_cast<GlfwRenderContext *>(glfwGetWindowUserPointer(window)); 223 if (that->onCursorPos_) { 224 that->onCursorPos_(x, y); 225 } 226 } 227 OnKey(GLFWwindow * window,int key,int scancode,int action,int mods)228 void GlfwRenderContext::OnKey(GLFWwindow *window, int key, int scancode, int action, int mods) 229 { 230 const auto &that = reinterpret_cast<GlfwRenderContext *>(glfwGetWindowUserPointer(window)); 231 if (that->onKey_) { 232 that->onKey_(key, scancode, action, mods); 233 } 234 } 235 OnChar(GLFWwindow * window,unsigned int codepoint)236 void GlfwRenderContext::OnChar(GLFWwindow *window, unsigned int codepoint) 237 { 238 const auto &that = reinterpret_cast<GlfwRenderContext *>(glfwGetWindowUserPointer(window)); 239 if (that->onChar_) { 240 that->onChar_(codepoint); 241 } 242 } 243 OnSizeChanged(GLFWwindow * window,int32_t width,int32_t height)244 void GlfwRenderContext::OnSizeChanged(GLFWwindow *window, int32_t width, int32_t height) 245 { 246 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "OnSizeChanged %{public}d %{public}d", width, height); 247 248 const auto &that = reinterpret_cast<GlfwRenderContext *>(glfwGetWindowUserPointer(window)); 249 if (that->width_ != width || that->height_ != height) { 250 glfwSetWindowSize(window, that->width_, that->height_); 251 } 252 that->onSizeChanged_(that->width_, that->height_); 253 ::OHOS::HiviewDFX::HiLog::Info(LABEL, "OnSizeChanged done %{public}d %{public}d", width, height); 254 } 255 } // namespace OHOS::Rosen 256