| /* |
| * Copyright 2023 The Cobalt Authors. All Rights Reserved. |
| * Copyright 2015 Google Inc. All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "glimp/egl/display_registry.h" |
| |
| #include <memory> |
| #include <utility> |
| |
| #include "glimp/egl/display_impl.h" |
| #include "glimp/egl/error.h" |
| |
| namespace glimp { |
| namespace egl { |
| |
| int DisplayRegistry::num_connections_ = 0; |
| DisplayRegistry::Connection |
| DisplayRegistry::connections_[DisplayRegistry::kMaxDisplays]; |
| |
| EGLDisplay DisplayRegistry::GetDisplay(EGLNativeDisplayType native_display) { |
| // Check to see if a display already exists for this native_display. If so, |
| // return it, otherwise create a new one and return that. |
| for (int i = 0; i < num_connections_; ++i) { |
| if (connections_[i].native_display == native_display) { |
| return reinterpret_cast<EGLDisplay>(&connections_[i]); |
| } |
| } |
| |
| // If the platform-specific implementation does not accept the specified |
| // |native_display|, return in error. |
| if (!DisplayImpl::IsValidNativeDisplayType(native_display)) { |
| return EGL_NO_DISPLAY; |
| } else { |
| // Create a new display connection (i.e. EGLDisplay), add it to our |
| // display mapping so it can be looked up later, and then return it. |
| SB_CHECK(num_connections_ < kMaxDisplays); |
| connections_[num_connections_].native_display = native_display; |
| connections_[num_connections_].display = NULL; |
| ++num_connections_; |
| return reinterpret_cast<EGLDisplay>(&connections_[num_connections_ - 1]); |
| } |
| } |
| |
| bool DisplayRegistry::InitializeDisplay(EGLDisplay display) { |
| SB_DCHECK(Valid(display)); |
| Connection* connection = reinterpret_cast<Connection*>(display); |
| if (!connection->display) { |
| std::unique_ptr<DisplayImpl> display_impl = |
| DisplayImpl::Create(connection->native_display); |
| // If the platform-specific glimp implementation rejected the native |
| // display, then we return false to indicate failure. |
| if (!display_impl) { |
| return false; |
| } |
| |
| connection->display = new Display(std::move(display_impl)); |
| } |
| |
| return true; |
| } |
| |
| void DisplayRegistry::TerminateDisplay(EGLDisplay display) { |
| SB_DCHECK(Valid(display)); |
| Connection* connection = reinterpret_cast<Connection*>(display); |
| |
| if (connection->display) { |
| delete connection->display; |
| connection->display = NULL; |
| } |
| } |
| |
| bool DisplayRegistry::Valid(EGLDisplay display) { |
| Connection* connection = reinterpret_cast<Connection*>(display); |
| for (int i = 0; i < num_connections_; ++i) { |
| if (connection == &connections_[i]) { |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| // This function will either return the Display object associated with the |
| // given EGLDisplay, or else set the appropriate EGL error and then return |
| // NULL. |
| egl::Display* GetDisplayOrSetError(EGLDisplay egl_display) { |
| if (!egl::DisplayRegistry::Valid(egl_display)) { |
| egl::SetError(EGL_BAD_DISPLAY); |
| return NULL; |
| } |
| egl::Display* display = egl::DisplayRegistry::ToDisplay(egl_display); |
| if (!display) { |
| egl::SetError(EGL_NOT_INITIALIZED); |
| return NULL; |
| } |
| |
| return display; |
| } |
| |
| } // namespace egl |
| } // namespace glimp |