1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
// Copyright (c) 2010 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 "chrome/renderer/pepper_platform_context_3d_impl.h"
#include "chrome/renderer/command_buffer_proxy.h"
#include "chrome/renderer/gpu_channel_host.h"
#include "chrome/renderer/render_thread.h"
#include "content/renderer/ggl.h"
#include "gpu/command_buffer/client/gles2_cmd_helper.h"
#include "gpu/command_buffer/client/gles2_implementation.h"
#ifdef ENABLE_GPU
PlatformContext3DImpl::PlatformContext3DImpl(ggl::Context* parent_context)
: parent_context_(parent_context),
parent_texture_id_(0),
command_buffer_(NULL),
callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
}
PlatformContext3DImpl::~PlatformContext3DImpl() {
if (command_buffer_) {
DCHECK(channel_.get());
channel_->DestroyCommandBuffer(command_buffer_);
command_buffer_ = NULL;
}
channel_ = NULL;
if (parent_context_ && parent_texture_id_ != 0) {
ggl::GetImplementation(parent_context_)->FreeTextureId(parent_texture_id_);
}
}
bool PlatformContext3DImpl::Init() {
// Ignore initializing more than once.
if (command_buffer_)
return true;
RenderThread* render_thread = RenderThread::current();
if (!render_thread)
return false;
channel_ = render_thread->GetGpuChannel();
if (!channel_.get())
return false;
DCHECK(channel_->state() == GpuChannelHost::kConnected);
// Flush any remaining commands in the parent context to make sure the
// texture id accounting stays consistent.
gpu::gles2::GLES2Implementation* parent_gles2 =
ggl::GetImplementation(parent_context_);
parent_gles2->helper()->CommandBufferHelper::Finish();
parent_texture_id_ = parent_gles2->MakeTextureId();
// TODO(apatrick): Let Pepper plugins configure their back buffer surface.
static const int32 kAttribs[] = {
ggl::GGL_ALPHA_SIZE, 8,
ggl::GGL_DEPTH_SIZE, 24,
ggl::GGL_STENCIL_SIZE, 8,
ggl::GGL_SAMPLES, 0,
ggl::GGL_SAMPLE_BUFFERS, 0,
ggl::GGL_NONE,
};
std::vector<int32> attribs(kAttribs, kAttribs + ARRAYSIZE_UNSAFE(kAttribs));
CommandBufferProxy* parent_command_buffer =
ggl::GetCommandBufferProxy(parent_context_);
command_buffer_ = channel_->CreateOffscreenCommandBuffer(
parent_command_buffer,
gfx::Size(1, 1),
"*",
attribs,
parent_texture_id_);
if (!command_buffer_)
return false;
command_buffer_->SetChannelErrorCallback(callback_factory_.NewCallback(
&PlatformContext3DImpl::OnContextLost));
return true;
}
void PlatformContext3DImpl::SetSwapBuffersCallback(Callback0::Type* callback) {
DCHECK(command_buffer_);
command_buffer_->SetSwapBuffersCallback(callback);
}
unsigned PlatformContext3DImpl::GetBackingTextureId() {
DCHECK(command_buffer_);
return parent_texture_id_;
}
gpu::CommandBuffer* PlatformContext3DImpl::GetCommandBuffer() {
return command_buffer_;
}
void PlatformContext3DImpl::SetContextLostCallback(Callback0::Type* callback) {
context_lost_callback_.reset(callback);
}
void PlatformContext3DImpl::OnContextLost() {
DCHECK(command_buffer_);
// We will lose the parent context soon (it will be reallocated by the main
// page).
parent_context_ = NULL;
parent_texture_id_ = 0;
if (context_lost_callback_.get())
context_lost_callback_->Run();
}
#endif // ENABLE_GPU
|