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
3 // found in the LICENSE file.
5 #include "content/common/gpu/image_transport_surface.h"
7 #include "base/command_line.h"
8 #include "base/logging.h"
9 #include "content/common/gpu/gpu_channel.h"
10 #include "content/common/gpu/gpu_channel_manager.h"
11 #include "content/common/gpu/gpu_command_buffer_stub.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"
15 #include "ui/gl/gl_surface_egl.h"
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
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
;
30 g_last_gpu_access_ticks
= base::TimeTicks::Now().ToInternalValue();
33 class ImageTransportSurfaceAndroid
34 : public NullTransportSurface
,
35 public base::SupportsWeakPtr
<ImageTransportSurfaceAndroid
> {
37 ImageTransportSurfaceAndroid(GpuChannelManager
* manager
,
38 GpuCommandBufferStub
* stub
,
39 const gfx::GLSurfaceHandle
& handle
);
41 // gfx::GLSurface implementation.
42 bool OnMakeCurrent(gfx::GLContext
* context
) override
;
43 void WakeUpGpu() override
;
46 ~ImageTransportSurfaceAndroid() override
;
49 void ScheduleWakeUp();
52 base::TimeTicks begin_wake_up_time_
;
55 class DirectSurfaceAndroid
: public PassThroughImageTransportSurface
{
57 DirectSurfaceAndroid(GpuChannelManager
* manager
,
58 GpuCommandBufferStub
* stub
,
59 gfx::GLSurface
* surface
);
61 // gfx::GLSurface implementation.
62 gfx::SwapResult
SwapBuffers() override
;
65 ~DirectSurfaceAndroid() override
;
68 DISALLOW_COPY_AND_ASSIGN(DirectSurfaceAndroid
);
71 ImageTransportSurfaceAndroid::ImageTransportSurfaceAndroid(
72 GpuChannelManager
* manager
,
73 GpuCommandBufferStub
* stub
,
74 const gfx::GLSurfaceHandle
& handle
)
75 : NullTransportSurface(manager
, stub
, handle
) {}
77 ImageTransportSurfaceAndroid::~ImageTransportSurfaceAndroid() {}
79 bool ImageTransportSurfaceAndroid::OnMakeCurrent(gfx::GLContext
* context
) {
84 void ImageTransportSurfaceAndroid::WakeUpGpu() {
85 begin_wake_up_time_
= base::TimeTicks::Now();
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
))
99 if (now
- begin_wake_up_time_
>
100 base::TimeDelta::FromMilliseconds(kMaxKeepAliveTimeMs
))
105 base::MessageLoop::current()->PostDelayedTask(
107 base::Bind(&ImageTransportSurfaceAndroid::ScheduleWakeUp
, AsWeakPtr()),
108 base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs
));
111 void ImageTransportSurfaceAndroid::DoWakeUpGpu() {
112 if (!GetHelper()->stub()->decoder() ||
113 !GetHelper()->stub()->decoder()->MakeCurrent())
119 DirectSurfaceAndroid::DirectSurfaceAndroid(GpuChannelManager
* manager
,
120 GpuCommandBufferStub
* stub
,
121 gfx::GLSurface
* surface
)
122 : PassThroughImageTransportSurface(manager
, stub
, surface
) {}
124 DirectSurfaceAndroid::~DirectSurfaceAndroid() {}
126 gfx::SwapResult
DirectSurfaceAndroid::SwapBuffers() {
128 return PassThroughImageTransportSurface::SwapBuffers();
131 } // anonymous namespace
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
));
144 scoped_refptr
<gfx::GLSurface
> ImageTransportSurface::CreateNativeSurface(
145 GpuChannelManager
* manager
,
146 GpuCommandBufferStub
* stub
,
147 const gfx::GLSurfaceHandle
& handle
) {
148 DCHECK(GpuSurfaceLookup::GetInstance());
149 DCHECK_EQ(handle
.transport_type
, gfx::NATIVE_DIRECT
);
150 ANativeWindow
* window
=
151 GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
153 CHECK(window
) << "Failed to retrieve window handle.";
154 scoped_refptr
<gfx::GLSurface
> surface
=
155 new gfx::NativeViewGLSurfaceEGL(window
);
156 bool initialize_success
= surface
->Initialize();
158 ANativeWindow_release(window
);
159 if (!initialize_success
)
160 return scoped_refptr
<gfx::GLSurface
>();
162 return scoped_refptr
<gfx::GLSurface
>(
163 new DirectSurfaceAndroid(manager
, stub
, surface
.get()));
166 } // namespace content