| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/common/gpu/image_transport_surface.h" | 5 #include "content/common/gpu/image_transport_surface.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "content/common/gpu/gpu_channel.h" | 9 #include "content/common/gpu/gpu_channel.h" |
| 10 #include "content/common/gpu/gpu_channel_manager.h" | 10 #include "content/common/gpu/gpu_channel_manager.h" |
| 11 #include "content/common/gpu/gpu_command_buffer_stub.h" | 11 #include "content/common/gpu/gpu_command_buffer_stub.h" |
| 12 #include "content/common/gpu/gpu_surface_lookup.h" | 12 #include "content/common/gpu/gpu_surface_lookup.h" |
| 13 #include "content/common/gpu/null_transport_surface.h" | |
| 14 #include "content/public/common/content_switches.h" | 13 #include "content/public/common/content_switches.h" |
| 15 #include "ui/gl/gl_surface_egl.h" | 14 #include "ui/gl/gl_surface_egl.h" |
| 16 | 15 |
| 17 namespace content { | 16 namespace content { |
| 18 namespace { | |
| 19 | |
| 20 // Amount of time the GPU is allowed to idle before it powers down. | |
| 21 const int kMaxGpuIdleTimeMs = 40; | |
| 22 // Maximum amount of time we keep pinging the GPU waiting for the client to | |
| 23 // draw. | |
| 24 const int kMaxKeepAliveTimeMs = 200; | |
| 25 // Last time we know the GPU was powered on. Global for tracking across all | |
| 26 // transport surfaces. | |
| 27 int64 g_last_gpu_access_ticks; | |
| 28 | |
| 29 void DidAccessGpu() { | |
| 30 g_last_gpu_access_ticks = base::TimeTicks::Now().ToInternalValue(); | |
| 31 } | |
| 32 | |
| 33 class ImageTransportSurfaceAndroid | |
| 34 : public NullTransportSurface, | |
| 35 public base::SupportsWeakPtr<ImageTransportSurfaceAndroid> { | |
| 36 public: | |
| 37 ImageTransportSurfaceAndroid(GpuChannelManager* manager, | |
| 38 GpuCommandBufferStub* stub, | |
| 39 const gfx::GLSurfaceHandle& handle); | |
| 40 | |
| 41 // gfx::GLSurface implementation. | |
| 42 bool OnMakeCurrent(gfx::GLContext* context) override; | |
| 43 void WakeUpGpu() override; | |
| 44 | |
| 45 protected: | |
| 46 ~ImageTransportSurfaceAndroid() override; | |
| 47 | |
| 48 private: | |
| 49 void ScheduleWakeUp(); | |
| 50 void DoWakeUpGpu(); | |
| 51 | |
| 52 base::TimeTicks begin_wake_up_time_; | |
| 53 }; | |
| 54 | |
| 55 class DirectSurfaceAndroid : public PassThroughImageTransportSurface { | |
| 56 public: | |
| 57 DirectSurfaceAndroid(GpuChannelManager* manager, | |
| 58 GpuCommandBufferStub* stub, | |
| 59 gfx::GLSurface* surface); | |
| 60 | |
| 61 // gfx::GLSurface implementation. | |
| 62 gfx::SwapResult SwapBuffers() override; | |
| 63 | |
| 64 protected: | |
| 65 ~DirectSurfaceAndroid() override; | |
| 66 | |
| 67 private: | |
| 68 DISALLOW_COPY_AND_ASSIGN(DirectSurfaceAndroid); | |
| 69 }; | |
| 70 | |
| 71 ImageTransportSurfaceAndroid::ImageTransportSurfaceAndroid( | |
| 72 GpuChannelManager* manager, | |
| 73 GpuCommandBufferStub* stub, | |
| 74 const gfx::GLSurfaceHandle& handle) | |
| 75 : NullTransportSurface(manager, stub, handle) {} | |
| 76 | |
| 77 ImageTransportSurfaceAndroid::~ImageTransportSurfaceAndroid() {} | |
| 78 | |
| 79 bool ImageTransportSurfaceAndroid::OnMakeCurrent(gfx::GLContext* context) { | |
| 80 DidAccessGpu(); | |
| 81 return true; | |
| 82 } | |
| 83 | |
| 84 void ImageTransportSurfaceAndroid::WakeUpGpu() { | |
| 85 begin_wake_up_time_ = base::TimeTicks::Now(); | |
| 86 ScheduleWakeUp(); | |
| 87 } | |
| 88 | |
| 89 void ImageTransportSurfaceAndroid::ScheduleWakeUp() { | |
| 90 base::TimeTicks now = base::TimeTicks::Now(); | |
| 91 base::TimeTicks last_access_time = | |
| 92 base::TimeTicks::FromInternalValue(g_last_gpu_access_ticks); | |
| 93 TRACE_EVENT2("gpu", "ImageTransportSurfaceAndroid::ScheduleWakeUp", | |
| 94 "idle_time", (now - last_access_time).InMilliseconds(), | |
| 95 "keep_awake_time", (now - begin_wake_up_time_).InMilliseconds()); | |
| 96 if (now - last_access_time < | |
| 97 base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs)) | |
| 98 return; | |
| 99 if (now - begin_wake_up_time_ > | |
| 100 base::TimeDelta::FromMilliseconds(kMaxKeepAliveTimeMs)) | |
| 101 return; | |
| 102 | |
| 103 DoWakeUpGpu(); | |
| 104 | |
| 105 base::MessageLoop::current()->PostDelayedTask( | |
| 106 FROM_HERE, | |
| 107 base::Bind(&ImageTransportSurfaceAndroid::ScheduleWakeUp, AsWeakPtr()), | |
| 108 base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs)); | |
| 109 } | |
| 110 | |
| 111 void ImageTransportSurfaceAndroid::DoWakeUpGpu() { | |
| 112 if (!GetHelper()->stub()->decoder() || | |
| 113 !GetHelper()->stub()->decoder()->MakeCurrent()) | |
| 114 return; | |
| 115 glFinish(); | |
| 116 DidAccessGpu(); | |
| 117 } | |
| 118 | |
| 119 DirectSurfaceAndroid::DirectSurfaceAndroid(GpuChannelManager* manager, | |
| 120 GpuCommandBufferStub* stub, | |
| 121 gfx::GLSurface* surface) | |
| 122 : PassThroughImageTransportSurface(manager, stub, surface) {} | |
| 123 | |
| 124 DirectSurfaceAndroid::~DirectSurfaceAndroid() {} | |
| 125 | |
| 126 gfx::SwapResult DirectSurfaceAndroid::SwapBuffers() { | |
| 127 DidAccessGpu(); | |
| 128 return PassThroughImageTransportSurface::SwapBuffers(); | |
| 129 } | |
| 130 | |
| 131 } // anonymous namespace | |
| 132 | |
| 133 // static | |
| 134 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateTransportSurface( | |
| 135 GpuChannelManager* manager, | |
| 136 GpuCommandBufferStub* stub, | |
| 137 const gfx::GLSurfaceHandle& handle) { | |
| 138 DCHECK_EQ(gfx::NULL_TRANSPORT, handle.transport_type); | |
| 139 return scoped_refptr<gfx::GLSurface>( | |
| 140 new ImageTransportSurfaceAndroid(manager, stub, handle)); | |
| 141 } | |
| 142 | 17 |
| 143 // static | 18 // static |
| 144 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface( | 19 scoped_refptr<gfx::GLSurface> ImageTransportSurface::CreateNativeSurface( |
| 145 GpuChannelManager* manager, | 20 GpuChannelManager* manager, |
| 146 GpuCommandBufferStub* stub, | 21 GpuCommandBufferStub* stub, |
| 147 const gfx::GLSurfaceHandle& handle) { | 22 const gfx::GLSurfaceHandle& handle) { |
| 148 DCHECK(GpuSurfaceLookup::GetInstance()); | 23 DCHECK(GpuSurfaceLookup::GetInstance()); |
| 149 DCHECK_EQ(handle.transport_type, gfx::NATIVE_DIRECT); | 24 DCHECK_EQ(handle.transport_type, gfx::NATIVE_DIRECT); |
| 150 ANativeWindow* window = | 25 ANativeWindow* window = |
| 151 GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( | 26 GpuSurfaceLookup::GetInstance()->AcquireNativeWidget( |
| 152 stub->surface_id()); | 27 stub->surface_id()); |
| 153 CHECK(window) << "Failed to retrieve window handle."; | 28 CHECK(window) << "Failed to retrieve window handle."; |
| 154 scoped_refptr<gfx::GLSurface> surface = | 29 scoped_refptr<gfx::GLSurface> surface = |
| 155 new gfx::NativeViewGLSurfaceEGL(window); | 30 new gfx::NativeViewGLSurfaceEGL(window); |
| 156 bool initialize_success = surface->Initialize(); | 31 bool initialize_success = surface->Initialize(); |
| 157 if (window) | 32 if (window) |
| 158 ANativeWindow_release(window); | 33 ANativeWindow_release(window); |
| 159 if (!initialize_success) | 34 if (!initialize_success) |
| 160 return scoped_refptr<gfx::GLSurface>(); | 35 return scoped_refptr<gfx::GLSurface>(); |
| 161 | 36 |
| 162 return scoped_refptr<gfx::GLSurface>( | 37 return scoped_refptr<gfx::GLSurface>( |
| 163 new DirectSurfaceAndroid(manager, stub, surface.get())); | 38 new PassThroughImageTransportSurface(manager, stub, surface.get())); |
| 164 } | 39 } |
| 165 | 40 |
| 166 } // namespace content | 41 } // namespace content |
| OLD | NEW |