Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 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. | |
| 4 | |
| 5 #include <GLES2/gl2.h> | |
| 6 #include <GLES2/gl2extmojo.h> | |
| 7 #include <MGL/mgl.h> | |
| 8 | |
| 9 #include "base/message_loop/message_loop.h" | |
| 10 #include "examples/ui/spinning_cube/spinning_cube_view.h" | |
| 11 | |
| 12 namespace examples { | |
| 13 | |
| 14 SpinningCubeView::SpinningCubeView( | |
| 15 mojo::ApplicationImpl* app, | |
| 16 const mojo::ui::ViewProvider::CreateViewCallback& callback) | |
| 17 : callback_(callback), | |
| 18 binding_(this), | |
| 19 context_owner_(app->shell()), | |
| 20 texture_cache_(context_owner_.context(), &resource_returner_), | |
| 21 surface_id_namespace_(0), | |
| 22 draw_scheduled_(false), | |
| 23 weak_ptr_factory_(this) { | |
| 24 app->ConnectToService("mojo:surfaces_service", &surfaces_); | |
| 25 app->ConnectToService("mojo:view_manager_service", &view_manager_); | |
| 26 | |
| 27 surfaces_->SetResourceReturner(resource_returner_.Pass()); | |
| 28 surfaces_->GetIdNamespace( | |
| 29 base::Bind(&SpinningCubeView::OnSurfaceIdNamespaceAvailable, | |
| 30 base::Unretained(this))); | |
| 31 | |
| 32 InitCube(); | |
| 33 } | |
| 34 | |
| 35 SpinningCubeView::~SpinningCubeView() {} | |
| 36 | |
| 37 void SpinningCubeView::OnSurfaceIdNamespaceAvailable(uint32_t id_namespace) { | |
| 38 surface_id_namespace_ = id_namespace; | |
| 39 InitView(); | |
| 40 } | |
| 41 | |
| 42 void SpinningCubeView::InitView() { | |
| 43 mojo::ui::ViewPtr view; | |
| 44 binding_.Bind(mojo::GetProxy(&view)); | |
| 45 view_manager_->RegisterView(view.Pass(), mojo::GetProxy(&view_host_), | |
| 46 callback_); | |
| 47 | |
| 48 view_host_->GetServiceProvider(mojo::GetProxy(&view_service_provider_)); | |
| 49 } | |
| 50 | |
| 51 void SpinningCubeView::OnLayout(mojo::ui::ViewLayoutParamsPtr layout_params, | |
| 52 mojo::Array<uint32_t> children_needing_layout, | |
| 53 const OnLayoutCallback& callback) { | |
| 54 // Create a new surface the first time or if the size has changed. | |
| 55 mojo::Size new_size; | |
| 56 new_size.width = layout_params->constraints->max_width; | |
| 57 new_size.height = layout_params->constraints->max_height; | |
| 58 if (!surface_id_ || !size_.Equals(new_size)) { | |
| 59 if (!surface_id_) { | |
| 60 surface_id_ = mojo::SurfaceId::New(); | |
| 61 surface_id_->id_namespace = surface_id_namespace_; | |
| 62 } else { | |
| 63 surfaces_->DestroySurface(surface_id_->local); | |
| 64 } | |
| 65 surface_id_->local++; | |
| 66 size_ = new_size; | |
| 67 surfaces_->CreateSurface(surface_id_->local); | |
| 68 } | |
| 69 | |
| 70 // Submit the new layout information. | |
| 71 mojo::ui::ViewLayoutInfoPtr info = mojo::ui::ViewLayoutInfo::New(); | |
|
jamesr
2015/10/27 23:04:23
i pretty much use 'auto' with these ::New() factor
jeffbrown
2015/10/27 23:48:16
Sure! That makes sense.
| |
| 72 info->size = size_.Clone(); | |
| 73 info->surface_id = surface_id_->Clone(); | |
| 74 callback.Run(info.Pass()); | |
| 75 | |
| 76 // Draw! | |
| 77 ScheduleDraw(); | |
| 78 } | |
| 79 | |
| 80 void SpinningCubeView::OnChildUnavailable( | |
| 81 uint32_t child_key, | |
| 82 const OnChildUnavailableCallback& callback) { | |
| 83 callback.Run(); | |
| 84 } | |
| 85 | |
| 86 void SpinningCubeView::InitCube() { | |
| 87 context_owner_.context()->MakeCurrent(); | |
| 88 cube_.Init(); | |
| 89 last_draw_ = mojo::GetTimeTicksNow(); | |
| 90 } | |
| 91 | |
| 92 void SpinningCubeView::DrawCube() { | |
| 93 draw_scheduled_ = false; | |
| 94 | |
| 95 context_owner_.context()->MakeCurrent(); | |
|
jamesr
2015/10/27 23:04:23
unless the context has to be current for the GetTe
jeffbrown
2015/10/27 23:48:16
It's needed by GetTexture although arguably that's
| |
| 96 | |
| 97 scoped_ptr<mojo::TextureCache::TextureInfo> texture_info = | |
| 98 texture_cache_.GetTexture(size_); | |
| 99 if (!texture_info) { | |
| 100 LOG(ERROR) << "Could not allocate texture of size " << size_.width << "x" | |
| 101 << size_.height; | |
| 102 return; | |
| 103 } | |
| 104 | |
| 105 scoped_ptr<mojo::GLTexture> texture = texture_info->TakeTexture(); | |
| 106 | |
| 107 GLuint fbo = 0u; | |
| 108 glGenFramebuffers(1, &fbo); | |
| 109 glBindFramebuffer(GL_FRAMEBUFFER, fbo); | |
| 110 GLuint depth_buffer = 0u; | |
| 111 glGenRenderbuffers(1, &depth_buffer); | |
| 112 glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer); | |
| 113 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size_.width, | |
| 114 size_.height); | |
| 115 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, | |
| 116 texture->texture_id(), 0); | |
| 117 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, | |
| 118 GL_RENDERBUFFER, depth_buffer); | |
| 119 DCHECK_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE), | |
| 120 glCheckFramebufferStatus(GL_FRAMEBUFFER)); | |
| 121 glClearColor(1, 0, 0, 0.5); | |
| 122 | |
| 123 cube_.set_size(size_.width, size_.height); | |
| 124 | |
| 125 MojoTimeTicks now = mojo::GetTimeTicksNow(); | |
| 126 MojoTimeTicks offset = now - last_draw_; | |
| 127 cube_.UpdateForTimeDelta(offset * 0.000001f); | |
| 128 last_draw_ = now; | |
| 129 | |
| 130 cube_.Draw(); | |
| 131 | |
| 132 glDeleteFramebuffers(1, &fbo); | |
| 133 glDeleteRenderbuffers(1, &depth_buffer); | |
| 134 | |
| 135 mojo::FramePtr frame = mojo::TextureUploader::GetUploadFrame( | |
| 136 context_owner_.context(), texture_info->resource_id(), texture); | |
| 137 surfaces_->SubmitFrame(surface_id_->local, frame.Pass(), | |
| 138 base::Bind(&SpinningCubeView::OnSurfaceSubmitted, | |
| 139 base::Unretained(this))); | |
| 140 | |
| 141 texture_cache_.NotifyPendingResourceReturn(texture_info->resource_id(), | |
| 142 texture.Pass()); | |
| 143 } | |
| 144 | |
| 145 void SpinningCubeView::OnSurfaceSubmitted() { | |
| 146 ScheduleDraw(); | |
| 147 } | |
| 148 | |
| 149 void SpinningCubeView::ScheduleDraw() { | |
| 150 if (!draw_scheduled_) { | |
| 151 draw_scheduled_ = true; | |
| 152 | |
| 153 // TODO(jeffbrown): For now, we need to throttle this down because | |
| 154 // drawing as fast as we can appears to cause starvation of the | |
| 155 // Mojo message loop and makes X11 unhappy. | |
| 156 base::MessageLoop::current()->PostDelayedTask( | |
| 157 FROM_HERE, | |
| 158 base::Bind(&SpinningCubeView::DrawCube, weak_ptr_factory_.GetWeakPtr()), | |
| 159 base::TimeDelta::FromMilliseconds(30)); | |
| 160 } | |
| 161 } | |
| 162 | |
| 163 } // namespace examples | |
| OLD | NEW |