Chromium Code Reviews| Index: chromecast/ozone/surface_factory_chromecast.cc |
| diff --git a/chromecast/ozone/surface_factory_chromecast.cc b/chromecast/ozone/surface_factory_chromecast.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d147abac69e48619a60bd3fa521881a3e6098f68 |
| --- /dev/null |
| +++ b/chromecast/ozone/surface_factory_chromecast.cc |
| @@ -0,0 +1,179 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| +#include "chromecast/ozone/surface_factory_chromecast.h" |
|
lcwu1
2015/03/27 00:51:43
Add a vertical space above.
halliwell
2015/03/27 01:45:03
Done.
|
| + |
| +#include "base/callback_helpers.h" |
| +#include "chromecast/ozone/chromecast_egl_platform.h" |
| +#include "chromecast/ozone/surface_ozone_egl_chromecast.h" |
| + |
| +namespace chromecast { |
| +namespace ozone { |
| + |
| +SurfaceFactoryChromecast::SurfaceFactoryChromecast( |
| + scoped_ptr<ChromecastEglPlatform> egl_platform) |
| + : state_(UNINITIALIZED), |
| + destroy_window_pending_state_(kNoDestroyPending), |
| + display_type_(0), |
| + window_(0), |
| + default_display_size_(egl_platform->GetDefaultDisplaySize()), |
| + display_size_(default_display_size_), |
| + new_display_size_(default_display_size_), |
| + egl_platform_(egl_platform.Pass()) { |
| +} |
| + |
| +SurfaceFactoryChromecast::~SurfaceFactoryChromecast() { |
| + DestroyDisplayTypeAndWindow(); |
| +} |
| + |
| +void SurfaceFactoryChromecast::InitializeHardware() { |
| + if (state_ == INITIALIZED) { |
| + return; |
| + } |
| + CHECK_EQ(state_, UNINITIALIZED); |
| + |
| + if (egl_platform_->InitializeHardware()) { |
| + state_ = INITIALIZED; |
| + } else { |
| + ShutdownHardware(); |
| + state_ = FAILED; |
| + } |
| +} |
| + |
| +void SurfaceFactoryChromecast::ShutdownHardware() { |
| + DestroyDisplayTypeAndWindow(); |
| + |
| + egl_platform_->ShutdownHardware(); |
| + |
| + state_ = UNINITIALIZED; |
| +} |
| + |
| +intptr_t SurfaceFactoryChromecast::GetNativeDisplay() { |
| + CreateDisplayTypeAndWindowIfNeeded(); |
| + return reinterpret_cast<intptr_t>(display_type_); |
| +} |
| + |
| +void SurfaceFactoryChromecast::CreateDisplayTypeAndWindowIfNeeded() { |
| + if (state_ == UNINITIALIZED) { |
| + InitializeHardware(); |
| + } |
| + if (new_display_size_ != display_size_) { |
| + DestroyDisplayTypeAndWindow(); |
| + display_size_ = new_display_size_; |
| + } |
| + DCHECK_EQ(state_, INITIALIZED); |
| + if (!display_type_) { |
| + display_type_ = egl_platform_->CreateDisplayType(display_size_); |
| + if (display_type_) { |
| + window_ = egl_platform_->CreateWindow(display_type_, display_size_); |
| + if (!window_) { |
| + DestroyDisplayTypeAndWindow(); |
|
derekjchow1
2015/03/19 21:28:02
Would it be reasonable to call ShutdownHardware he
halliwell
2015/03/19 22:21:58
We're about to terminate here (FATAL) so I'm not c
|
| + state_ = FAILED; |
| + LOG(FATAL) << "Create EGLNativeWindowType(" << display_size_.ToString() |
| + << ") failed."; |
| + } |
| + } else { |
| + state_ = FAILED; |
|
derekjchow1
2015/03/19 21:28:02
Ditto.
|
| + LOG(FATAL) << "Create EGLNativeDisplayType(" << display_size_.ToString() |
| + << ") failed."; |
| + } |
| + } |
| +} |
| + |
| +intptr_t SurfaceFactoryChromecast::GetNativeWindow() { |
| + CreateDisplayTypeAndWindowIfNeeded(); |
| + return window_; |
| +} |
| + |
| +bool SurfaceFactoryChromecast::ResizeDisplay(gfx::Size size) { |
| + // set size to at least 1280x720 even if passed 1x1 |
| + size.SetToMax(default_display_size_); |
| + if (display_type_ && size != display_size_) { |
| + DestroyDisplayTypeAndWindow(); |
| + } |
| + display_size_ = size; |
| + return true; |
| +} |
| + |
| +void SurfaceFactoryChromecast::DestroyDisplayTypeAndWindow() { |
| + if (window_) { |
| + egl_platform_->DestroyWindow(window_); |
| + window_ = 0; |
| + } |
| + if (display_type_) { |
| + egl_platform_->DestroyDisplayType(display_type_); |
| + display_type_ = 0; |
| + } |
| +} |
| + |
| +scoped_ptr<ui::SurfaceOzoneEGL> |
| +SurfaceFactoryChromecast::CreateEGLSurfaceForWidget( |
| + gfx::AcceleratedWidget widget) { |
| + new_display_size_ = gfx::Size(widget >> 16, widget & 0xFFFF); |
| + new_display_size_.SetToMax(default_display_size_); |
| + destroy_window_pending_state_ = kSurfaceExists; |
| + SendRelinquishResponse(); |
| + return make_scoped_ptr<ui::SurfaceOzoneEGL>( |
| + new SurfaceOzoneEglChromecast(this)); |
| +} |
| + |
| +void SurfaceFactoryChromecast::SetToRelinquishDisplay( |
| + const base::Closure& callback) { |
| + // This is called in response to a RelinquishDisplay message from the |
| + // browser task. This call may come before or after the display surface |
| + // is actually destroyed. |
| + relinquish_display_callback_ = callback; |
| + switch (destroy_window_pending_state_) { |
| + case kNoDestroyPending: |
| + case kSurfaceDestroyedRecently: |
| + DestroyDisplayTypeAndWindow(); |
| + SendRelinquishResponse(); |
| + destroy_window_pending_state_ = kNoDestroyPending; |
| + break; |
| + case kSurfaceExists: |
| + destroy_window_pending_state_ = kWindowDestroyPending; |
| + break; |
| + case kWindowDestroyPending: |
| + break; |
| + default: |
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +void SurfaceFactoryChromecast::ChildDestroyed() { |
| + if (destroy_window_pending_state_ == kWindowDestroyPending) { |
| + DestroyDisplayTypeAndWindow(); |
| + SendRelinquishResponse(); |
| + destroy_window_pending_state_ = kNoDestroyPending; |
| + } else { |
| + destroy_window_pending_state_ = kSurfaceDestroyedRecently; |
| + } |
| +} |
| + |
| +void SurfaceFactoryChromecast::SendRelinquishResponse() { |
| + if (!relinquish_display_callback_.is_null()) { |
| + base::ResetAndReturn(&relinquish_display_callback_).Run(); |
| + } |
| +} |
| + |
| +const int32* SurfaceFactoryChromecast::GetEGLSurfaceProperties( |
| + const int32* desired_list) { |
| + return egl_platform_->GetEGLSurfaceProperties(desired_list); |
| +} |
| + |
| +bool SurfaceFactoryChromecast::LoadEGLGLES2Bindings( |
| + AddGLLibraryCallback add_gl_library, |
| + SetGLGetProcAddressProcCallback set_gl_get_proc_address) { |
| + if (state_ != INITIALIZED) { |
| + InitializeHardware(); |
| + if (state_ != INITIALIZED) { |
| + return false; |
| + } |
| + } |
| + |
| + return egl_platform_->LoadEGLGLES2Bindings(add_gl_library, |
| + set_gl_get_proc_address); |
| +} |
| + |
| +} // namespace ozone |
| +} // namespace chromecast |