Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / common / gpu / image_transport_surface_android.cc
blob5e0d6ff11de257a6a158242e0bb5c4a24911cc59
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"
17 namespace content {
18 namespace {
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;
29 void DidAccessGpu() {
30 g_last_gpu_access_ticks = base::TimeTicks::Now().ToInternalValue();
33 class ImageTransportSurfaceAndroid
34 : public PassThroughImageTransportSurface,
35 public base::SupportsWeakPtr<ImageTransportSurfaceAndroid> {
36 public:
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;
48 protected:
49 virtual ~ImageTransportSurfaceAndroid();
51 private:
52 void ScheduleWakeUp();
53 void DoWakeUpGpu();
55 uint32 parent_client_id_;
56 base::TimeTicks begin_wake_up_time_;
59 class DirectSurfaceAndroid : public PassThroughImageTransportSurface {
60 public:
61 DirectSurfaceAndroid(GpuChannelManager* manager,
62 GpuCommandBufferStub* stub,
63 gfx::GLSurface* surface);
65 // gfx::GLSurface implementation.
66 virtual bool SwapBuffers() OVERRIDE;
68 protected:
69 virtual ~DirectSurfaceAndroid();
71 private:
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() {
86 if (!surface())
87 return false;
89 if (!PassThroughImageTransportSurface::Initialize())
90 return false;
92 GpuChannel* parent_channel =
93 GetHelper()->manager()->LookupChannel(parent_client_id_);
94 if (parent_channel) {
95 const base::CommandLine* command_line =
96 base::CommandLine::ForCurrentProcess();
97 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess))
98 GetHelper()->SetPreemptByFlag(parent_channel->GetPreemptionFlag());
101 return true;
104 bool ImageTransportSurfaceAndroid::OnMakeCurrent(gfx::GLContext* context) {
105 DidAccessGpu();
106 return true;
109 bool ImageTransportSurfaceAndroid::SwapBuffers() {
110 NOTREACHED();
111 return false;
114 void ImageTransportSurfaceAndroid::WakeUpGpu() {
115 begin_wake_up_time_ = base::TimeTicks::Now();
116 ScheduleWakeUp();
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))
128 return;
129 if (now - begin_wake_up_time_ >
130 base::TimeDelta::FromMilliseconds(kMaxKeepAliveTimeMs))
131 return;
133 DoWakeUpGpu();
135 base::MessageLoop::current()->PostDelayedTask(
136 FROM_HERE,
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())
144 return;
145 glFinish();
146 DidAccessGpu();
149 DirectSurfaceAndroid::DirectSurfaceAndroid(GpuChannelManager* manager,
150 GpuCommandBufferStub* stub,
151 gfx::GLSurface* surface)
152 : PassThroughImageTransportSurface(manager, stub, surface) {}
154 DirectSurfaceAndroid::~DirectSurfaceAndroid() {}
156 bool DirectSurfaceAndroid::SwapBuffers() {
157 DidAccessGpu();
158 return PassThroughImageTransportSurface::SwapBuffers();
161 } // anonymous namespace
163 // static
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,
171 stub,
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(
180 stub->surface_id());
181 scoped_refptr<gfx::GLSurface> surface =
182 new gfx::NativeViewGLSurfaceEGL(window);
183 bool initialize_success = surface->Initialize();
184 if (window)
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