Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(504)

Side by Side Diff: examples/ganesh_app/painter.cc

Issue 728593003: Add a sample app that draws with Ganesh (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Review comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « examples/ganesh_app/painter.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "examples/surfaces_app/child_gl_impl.h" 5 #include "examples/ganesh_app/painter.h"
6 6
7 #ifndef GL_GLEXT_PROTOTYPES 7 #ifndef GL_GLEXT_PROTOTYPES
8 #define GL_GLEXT_PROTOTYPES 8 #define GL_GLEXT_PROTOTYPES
9 #endif 9 #endif
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
13 #include "cc/output/compositor_frame.h" 14 #include "cc/output/compositor_frame.h"
14 #include "cc/output/delegated_frame_data.h" 15 #include "cc/output/delegated_frame_data.h"
15 #include "cc/quads/render_pass.h" 16 #include "cc/quads/render_pass.h"
16 #include "cc/quads/texture_draw_quad.h" 17 #include "cc/quads/texture_draw_quad.h"
17 #include "examples/surfaces_app/surfaces_util.h" 18 #include "examples/surfaces_app/surfaces_util.h"
18 #include "gpu/GLES2/gl2chromium.h" 19 #include "gpu/GLES2/gl2chromium.h"
19 #include "gpu/GLES2/gl2extchromium.h" 20 #include "gpu/GLES2/gl2extchromium.h"
21 #include "gpu/command_buffer/client/gles2_interface.h"
22 #include "gpu/command_buffer/client/gles2_lib.h"
20 #include "gpu/command_buffer/common/mailbox.h" 23 #include "gpu/command_buffer/common/mailbox.h"
21 #include "gpu/command_buffer/common/mailbox_holder.h" 24 #include "gpu/command_buffer/common/mailbox_holder.h"
25 #include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h"
22 #include "mojo/converters/geometry/geometry_type_converters.h" 26 #include "mojo/converters/geometry/geometry_type_converters.h"
23 #include "mojo/converters/surfaces/surfaces_type_converters.h" 27 #include "mojo/converters/surfaces/surfaces_type_converters.h"
28 #include "mojo/public/c/gles2/gles2.h"
24 #include "mojo/public/cpp/application/application_connection.h" 29 #include "mojo/public/cpp/application/application_connection.h"
25 #include "mojo/public/cpp/environment/environment.h" 30 #include "mojo/public/cpp/environment/environment.h"
26 #include "mojo/services/public/interfaces/surfaces/surface_id.mojom.h" 31 #include "mojo/services/public/interfaces/surfaces/surface_id.mojom.h"
27 #include "mojo/services/public/interfaces/surfaces/surfaces.mojom.h" 32 #include "mojo/services/public/interfaces/surfaces/surfaces.mojom.h"
28 #include "third_party/khronos/GLES2/gl2.h" 33 #include "third_party/khronos/GLES2/gl2.h"
29 #include "third_party/khronos/GLES2/gl2ext.h" 34 #include "third_party/khronos/GLES2/gl2ext.h"
35 #include "third_party/skia/include/core/SkCanvas.h"
36 #include "third_party/skia/include/core/SkSurface.h"
37 #include "third_party/skia/include/gpu/gl/GrGLInterface.h"
30 #include "ui/gfx/rect.h" 38 #include "ui/gfx/rect.h"
31 #include "ui/gfx/transform.h" 39 #include "ui/gfx/transform.h"
32 40
33 namespace mojo {
34 namespace examples {
35
36 using cc::RenderPass; 41 using cc::RenderPass;
37 using cc::RenderPassId; 42 using cc::RenderPassId;
38 using cc::DrawQuad; 43 using cc::DrawQuad;
39 using cc::TextureDrawQuad; 44 using cc::TextureDrawQuad;
40 using cc::DelegatedFrameData; 45 using cc::DelegatedFrameData;
41 using cc::CompositorFrame; 46 using cc::CompositorFrame;
42 47
48 namespace mojo {
49 namespace examples {
50 namespace {
51
52 // The limit of the number of GPU resources we hold in the GrContext's
53 // GPU cache.
54 const int kMaxGaneshResourceCacheCount = 2048;
55
56 // The limit of the bytes allocated toward GPU resources in the GrContext's
57 // GPU cache.
58 const size_t kMaxGaneshResourceCacheBytes = 96 * 1024 * 1024;
59
60 }
61
43 static void ContextLostThunk(void*) { 62 static void ContextLostThunk(void*) {
44 LOG(FATAL) << "Context lost"; 63 LOG(FATAL) << "Context lost";
45 } 64 }
46 65
47 ChildGLImpl::ChildGLImpl(ApplicationConnection* surfaces_service_connection, 66 Painter::Painter(ApplicationConnection* surfaces_service_connection,
48 CommandBufferPtr command_buffer) 67 CommandBufferPtr command_buffer)
49 : start_time_(base::TimeTicks::Now()), 68 : next_resource_id_(0),
50 next_resource_id_(1),
51 weak_factory_(this) { 69 weak_factory_(this) {
52 surfaces_service_connection->ConnectToService(&surfaces_service_); 70 surfaces_service_connection->ConnectToService(&surfaces_service_);
53 surfaces_service_->CreateSurfaceConnection(base::Bind( 71 surfaces_service_->CreateSurfaceConnection(base::Bind(
54 &ChildGLImpl::SurfaceConnectionCreated, weak_factory_.GetWeakPtr())); 72 &Painter::SurfaceConnectionCreated, weak_factory_.GetWeakPtr()));
55 context_ = 73 context_ =
56 MojoGLES2CreateContext(command_buffer.PassMessagePipe().release().value(), 74 MojoGLES2CreateContext(command_buffer.PassMessagePipe().release().value(),
57 &ContextLostThunk, 75 &ContextLostThunk,
58 this, 76 this,
59 Environment::GetDefaultAsyncWaiter()); 77 mojo::Environment::GetDefaultAsyncWaiter());
60 DCHECK(context_); 78 DCHECK(context_);
61 MojoGLES2MakeCurrent(context_); 79 MojoGLES2MakeCurrent(context_);
80
81 gpu::gles2::GLES2Interface* gl = static_cast<gpu::gles2::GLES2Interface*>(
82 MojoGLES2GetGLES2Interface(context_));
83 gles2::SetGLContext(gl);
84
85 skia::RefPtr<GrGLInterface> interface = skia::AdoptRef(
86 skia_bindings::CreateCommandBufferSkiaGLBinding());
87 DCHECK(interface);
88
89 gr_context_ = skia::AdoptRef(GrContext::Create(
90 kOpenGL_GrBackend,
91 reinterpret_cast<GrBackendContext>(interface.get())));
92 DCHECK(gr_context_);
93 gr_context_->setResourceCacheLimits(kMaxGaneshResourceCacheCount,
94 kMaxGaneshResourceCacheBytes);
62 } 95 }
63 96
64 ChildGLImpl::~ChildGLImpl() { 97 Painter::~Painter() {
65 MojoGLES2DestroyContext(context_); 98 MojoGLES2DestroyContext(context_);
66 surface_->DestroySurface(mojo::SurfaceId::From(id_)); 99 surface_->DestroySurface(mojo::SurfaceId::From(id_));
67 } 100 }
68 101
69 void ChildGLImpl::ProduceFrame( 102 void Painter::ProduceFrame(
70 ColorPtr color, 103 ColorPtr color,
71 SizePtr size, 104 SizePtr size,
72 const mojo::Callback<void(SurfaceIdPtr id)>& callback) { 105 const mojo::Callback<void(SurfaceIdPtr id)>& callback) {
73 color_ = color.To<SkColor>(); 106
74 size_ = size.To<gfx::Size>(); 107 size_ = size.To<gfx::Size>();
75 cube_.Init(size_.width(), size_.height());
76 cube_.set_color(
77 SkColorGetR(color_), SkColorGetG(color_), SkColorGetB(color_));
78 produce_callback_ = callback; 108 produce_callback_ = callback;
79 AllocateSurface(); 109 AllocateSurface();
80 } 110 }
81 111
82 void ChildGLImpl::SurfaceConnectionCreated(SurfacePtr surface, 112 void Painter::SurfaceConnectionCreated(SurfacePtr surface,
83 uint32_t id_namespace) { 113 uint32_t id_namespace) {
84 surface_ = surface.Pass(); 114 surface_ = surface.Pass();
85 surface_.set_client(this); 115 surface_.set_client(this);
86 allocator_.reset(new cc::SurfaceIdAllocator(id_namespace)); 116 allocator_.reset(new cc::SurfaceIdAllocator(id_namespace));
87 AllocateSurface(); 117 AllocateSurface();
88 } 118 }
89 119
90 void ChildGLImpl::ReturnResources(Array<ReturnedResourcePtr> resources) { 120 void Painter::ReturnResources(Array<ReturnedResourcePtr> resources) {
91 for (size_t i = 0; i < resources.size(); ++i) { 121 for (size_t i = 0; i < resources.size(); ++i) {
92 cc::ReturnedResource res = resources[i].To<cc::ReturnedResource>(); 122 cc::ReturnedResource res = resources[i].To<cc::ReturnedResource>();
93 GLuint returned_texture = id_to_tex_map_[res.id]; 123 GLuint returned_texture = id_to_tex_map_[res.id];
94 glDeleteTextures(1, &returned_texture); 124 glDeleteTextures(1, &returned_texture);
95 } 125 }
96 } 126 }
97 127
98 void ChildGLImpl::AllocateSurface() { 128 void Painter::AllocateSurface() {
99 if (produce_callback_.is_null() || !allocator_) 129 if (produce_callback_.is_null() || !allocator_)
100 return; 130 return;
101 131
102 id_ = allocator_->GenerateId(); 132 id_ = allocator_->GenerateId();
103 surface_->CreateSurface(mojo::SurfaceId::From(id_), mojo::Size::From(size_)); 133 surface_->CreateSurface(mojo::SurfaceId::From(id_), mojo::Size::From(size_));
104 produce_callback_.Run(SurfaceId::From(id_)); 134 produce_callback_.Run(SurfaceId::From(id_));
105 Draw(); 135 Draw();
106 } 136 }
107 137
108 void ChildGLImpl::Draw() { 138 void Painter::Draw() {
109 // First, generate a GL texture and draw the cube into it. 139 gpu::gles2::GLES2Interface* gl = static_cast<gpu::gles2::GLES2Interface*>(
110 GLuint texture = 0u; 140 MojoGLES2GetGLES2Interface(context_));
111 glGenTextures(1, &texture); 141
112 glBindTexture(GL_TEXTURE_2D, texture); 142 GLuint texture_id = 0u;
113 glTexImage2D(GL_TEXTURE_2D, 143 gl->GenTextures(1, &texture_id);
114 0, 144 gl->BindTexture(GL_TEXTURE_2D, texture_id);
115 GL_RGBA, 145 gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.width(), size_.height(),
116 size_.width(), 146 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
117 size_.height(), 147 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
118 0, 148
119 GL_RGBA, 149 GrBackendTextureDesc desc;
120 GL_UNSIGNED_BYTE, 150 desc.fFlags = kRenderTarget_GrBackendTextureFlag;
121 0); 151 desc.fWidth = size_.width();
122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 152 desc.fHeight = size_.height();
123 GLuint fbo = 0u; 153 desc.fConfig = kSkia8888_GrPixelConfig;
124 glGenFramebuffers(1, &fbo); 154 desc.fOrigin = kTopLeft_GrSurfaceOrigin;
125 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 155 desc.fTextureHandle = texture_id;
126 glFramebufferTexture2D( 156 skia::RefPtr<GrTexture> texture = skia::AdoptRef(
127 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); 157 gr_context_->wrapBackendTexture(desc));
128 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), 158
129 glCheckFramebufferStatus(GL_FRAMEBUFFER)); 159 DCHECK(texture) << "No texture";
130 glClearColor(1, 0, 0, 0.5); 160 DCHECK(texture->asRenderTarget()) << "No render target";
131 cube_.UpdateForTimeDelta(0.16f); 161
132 cube_.Draw(); 162 skia::RefPtr<SkSurface> sk_surface = skia::AdoptRef(
163 SkSurface::NewRenderTargetDirect(texture->asRenderTarget()));
164
165 DCHECK(sk_surface);
166
167 SkCanvas* canvas = sk_surface->getCanvas();
168
169 SkPaint paint;
170 paint.setColor(SK_ColorRED);
171 paint.setFlags(SkPaint::kAntiAlias_Flag);
172 canvas->drawCircle(size_.width() / 2, 0, 100, paint);
173 canvas->flush();
133 174
134 // Then, put the texture into a mailbox. 175 // Then, put the texture into a mailbox.
135 gpu::Mailbox mailbox = gpu::Mailbox::Generate(); 176 gpu::Mailbox mailbox = gpu::Mailbox::Generate();
136 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); 177 glProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
137 GLuint sync_point = glInsertSyncPointCHROMIUM(); 178 GLuint sync_point = glInsertSyncPointCHROMIUM();
138 gpu::MailboxHolder holder(mailbox, GL_TEXTURE_2D, sync_point); 179 gpu::MailboxHolder holder(mailbox, GL_TEXTURE_2D, sync_point);
139 180
140 // Then, put the mailbox into a TransferableResource 181 // Then, put the mailbox into a TransferableResource
141 cc::TransferableResource resource; 182 cc::TransferableResource resource;
142 resource.id = next_resource_id_++; 183 resource.id = next_resource_id_++;
143 id_to_tex_map_[resource.id] = texture; 184 id_to_tex_map_[resource.id] = texture_id;
144 resource.format = cc::RGBA_8888; 185 resource.format = cc::RGBA_8888;
145 resource.filter = GL_LINEAR; 186 resource.filter = GL_LINEAR;
146 resource.size = size_; 187 resource.size = size_;
147 resource.mailbox_holder = holder; 188 resource.mailbox_holder = holder;
148 resource.is_repeated = false; 189 resource.is_repeated = false;
149 resource.is_software = false; 190 resource.is_software = false;
150 191
151 gfx::Rect rect(size_); 192 gfx::Rect rect(size_);
152 RenderPassId id(1, 1); 193 cc::RenderPassId id(1, 1);
153 scoped_ptr<RenderPass> pass = RenderPass::Create(); 194 scoped_ptr<RenderPass> pass = RenderPass::Create();
154 pass->SetNew(id, rect, rect, gfx::Transform()); 195 pass->SetNew(id, rect, rect, gfx::Transform());
155 196
156 CreateAndAppendSimpleSharedQuadState(pass.get(), gfx::Transform(), size_); 197 CreateAndAppendSimpleSharedQuadState(pass.get(), gfx::Transform(), size_);
157 198
158 TextureDrawQuad* texture_quad = 199 TextureDrawQuad* texture_quad =
159 pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); 200 pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
160 float vertex_opacity[4] = {1.0f, 1.0f, 0.2f, 1.0f}; 201 float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f};
161 texture_quad->SetNew(pass->shared_quad_state_list.back(), 202 texture_quad->SetNew(pass->shared_quad_state_list.back(),
162 rect, 203 rect,
163 rect, 204 rect,
164 rect, 205 rect,
165 resource.id, 206 resource.id,
166 true, 207 true,
167 gfx::PointF(), 208 gfx::PointF(),
168 gfx::PointF(1.f, 1.f), 209 gfx::PointF(1.f, 1.f),
169 SK_ColorBLUE, 210 SK_ColorBLUE,
170 vertex_opacity, 211 vertex_opacity,
171 false); 212 false);
172 213
173 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData); 214 scoped_ptr<DelegatedFrameData> delegated_frame_data(new DelegatedFrameData);
174 delegated_frame_data->render_pass_list.push_back(pass.Pass()); 215 delegated_frame_data->render_pass_list.push_back(pass.Pass());
175 delegated_frame_data->resource_list.push_back(resource); 216 delegated_frame_data->resource_list.push_back(resource);
176 217
177 scoped_ptr<CompositorFrame> frame(new CompositorFrame); 218 scoped_ptr<CompositorFrame> frame(new CompositorFrame);
178 frame->delegated_frame_data = delegated_frame_data.Pass(); 219 frame->delegated_frame_data = delegated_frame_data.Pass();
179 220
180 surface_->SubmitFrame(mojo::SurfaceId::From(id_), mojo::Frame::From(*frame)); 221 surface_->SubmitFrame(mojo::SurfaceId::From(id_), mojo::Frame::From(*frame));
181 222
182 base::MessageLoop::current()->PostDelayedTask( 223 base::MessageLoop::current()->PostDelayedTask(
183 FROM_HERE, 224 FROM_HERE,
184 base::Bind(&ChildGLImpl::Draw, base::Unretained(this)), 225 base::Bind(&Painter::Draw, weak_factory_.GetWeakPtr()),
185 base::TimeDelta::FromMilliseconds(50)); 226 base::TimeDelta::FromMilliseconds(50));
186 } 227 }
187 228
188 } // namespace examples 229 } // namespace examples
189 } // namespace mojo 230 } // namespace mojo
OLDNEW
« no previous file with comments | « examples/ganesh_app/painter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698