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/image_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 PassThroughImageTransportSurface
,
35 public base::SupportsWeakPtr
<ImageTransportSurfaceAndroid
> {
37 ImageTransportSurfaceAndroid(GpuChannelManager
* manager
,
38 GpuCommandBufferStub
* stub
,
39 gfx::GLSurface
* surface
,
40 uint32 parent_client_id
);
42 // gfx::GLSurface implementation.
43 virtual bool Initialize() OVERRIDE
;
44 virtual bool SwapBuffers() OVERRIDE
;
45 virtual bool OnMakeCurrent(gfx::GLContext
* context
) OVERRIDE
;
46 virtual void WakeUpGpu() OVERRIDE
;
49 virtual ~ImageTransportSurfaceAndroid();
52 void ScheduleWakeUp();
55 uint32 parent_client_id_
;
56 base::TimeTicks begin_wake_up_time_
;
59 class DirectSurfaceAndroid
: public PassThroughImageTransportSurface
{
61 DirectSurfaceAndroid(GpuChannelManager
* manager
,
62 GpuCommandBufferStub
* stub
,
63 gfx::GLSurface
* surface
);
65 // gfx::GLSurface implementation.
66 virtual bool SwapBuffers() OVERRIDE
;
69 virtual ~DirectSurfaceAndroid();
72 DISALLOW_COPY_AND_ASSIGN(DirectSurfaceAndroid
);
75 ImageTransportSurfaceAndroid::ImageTransportSurfaceAndroid(
76 GpuChannelManager
* manager
,
77 GpuCommandBufferStub
* stub
,
78 gfx::GLSurface
* surface
,
79 uint32 parent_client_id
)
80 : PassThroughImageTransportSurface(manager
, stub
, surface
),
81 parent_client_id_(parent_client_id
) {}
83 ImageTransportSurfaceAndroid::~ImageTransportSurfaceAndroid() {}
85 bool ImageTransportSurfaceAndroid::Initialize() {
89 if (!PassThroughImageTransportSurface::Initialize())
92 GpuChannel
* parent_channel
=
93 GetHelper()->manager()->LookupChannel(parent_client_id_
);
95 const base::CommandLine
* command_line
=
96 base::CommandLine::ForCurrentProcess();
97 if (command_line
->HasSwitch(switches::kUIPrioritizeInGpuProcess
))
98 GetHelper()->SetPreemptByFlag(parent_channel
->GetPreemptionFlag());
104 bool ImageTransportSurfaceAndroid::OnMakeCurrent(gfx::GLContext
* context
) {
109 bool ImageTransportSurfaceAndroid::SwapBuffers() {
114 void ImageTransportSurfaceAndroid::WakeUpGpu() {
115 begin_wake_up_time_
= base::TimeTicks::Now();
119 void ImageTransportSurfaceAndroid::ScheduleWakeUp() {
120 base::TimeTicks now
= base::TimeTicks::Now();
121 base::TimeTicks last_access_time
=
122 base::TimeTicks::FromInternalValue(g_last_gpu_access_ticks
);
123 TRACE_EVENT2("gpu", "ImageTransportSurfaceAndroid::ScheduleWakeUp",
124 "idle_time", (now
- last_access_time
).InMilliseconds(),
125 "keep_awake_time", (now
- begin_wake_up_time_
).InMilliseconds());
126 if (now
- last_access_time
<
127 base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs
))
129 if (now
- begin_wake_up_time_
>
130 base::TimeDelta::FromMilliseconds(kMaxKeepAliveTimeMs
))
135 base::MessageLoop::current()->PostDelayedTask(
137 base::Bind(&ImageTransportSurfaceAndroid::ScheduleWakeUp
, AsWeakPtr()),
138 base::TimeDelta::FromMilliseconds(kMaxGpuIdleTimeMs
));
141 void ImageTransportSurfaceAndroid::DoWakeUpGpu() {
142 if (!GetHelper()->stub()->decoder() ||
143 !GetHelper()->stub()->decoder()->MakeCurrent())
149 DirectSurfaceAndroid::DirectSurfaceAndroid(GpuChannelManager
* manager
,
150 GpuCommandBufferStub
* stub
,
151 gfx::GLSurface
* surface
)
152 : PassThroughImageTransportSurface(manager
, stub
, surface
) {}
154 DirectSurfaceAndroid::~DirectSurfaceAndroid() {}
156 bool DirectSurfaceAndroid::SwapBuffers() {
158 return PassThroughImageTransportSurface::SwapBuffers();
161 } // anonymous namespace
164 scoped_refptr
<gfx::GLSurface
> ImageTransportSurface::CreateNativeSurface(
165 GpuChannelManager
* manager
,
166 GpuCommandBufferStub
* stub
,
167 const gfx::GLSurfaceHandle
& handle
) {
168 if (handle
.transport_type
== gfx::NATIVE_TRANSPORT
) {
169 return scoped_refptr
<gfx::GLSurface
>(
170 new ImageTransportSurfaceAndroid(manager
,
172 manager
->GetDefaultOffscreenSurface(),
173 handle
.parent_client_id
));
176 DCHECK(GpuSurfaceLookup::GetInstance());
177 DCHECK_EQ(handle
.transport_type
, gfx::NATIVE_DIRECT
);
178 ANativeWindow
* window
=
179 GpuSurfaceLookup::GetInstance()->AcquireNativeWidget(
181 scoped_refptr
<gfx::GLSurface
> surface
=
182 new gfx::NativeViewGLSurfaceEGL(window
);
183 bool initialize_success
= surface
->Initialize();
185 ANativeWindow_release(window
);
186 if (!initialize_success
)
187 return scoped_refptr
<gfx::GLSurface
>();
189 return scoped_refptr
<gfx::GLSurface
>(
190 new DirectSurfaceAndroid(manager
, stub
, surface
.get()));
193 } // namespace content