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

Side by Side Diff: services/ui/public/cpp/bitmap_uploader.cc

Issue 2247023002: services/ui: Move BitmapUploader into mus_demo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@rm-software-output-device-mus
Patch Set: Created 4 years, 4 months 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 | « services/ui/public/cpp/bitmap_uploader.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
(Empty)
1 // Copyright 2015 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 "services/ui/public/cpp/bitmap_uploader.h"
6
7 #include <stddef.h>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "cc/ipc/compositor_frame.mojom.h"
13 #include "cc/quads/render_pass.h"
14 #include "cc/quads/solid_color_draw_quad.h"
15 #include "cc/quads/texture_draw_quad.h"
16 #include "services/ui/public/cpp/gles2_context.h"
17 #include "services/ui/public/cpp/window.h"
18 #include "services/ui/public/cpp/window_surface.h"
19
20 namespace ui {
21 namespace {
22
23 const uint32_t g_transparent_color = 0x00000000;
24
25 } // namespace
26
27 const char kBitmapUploaderForAcceleratedWidget[] =
28 "__BITMAP_UPLOADER_ACCELERATED_WIDGET__";
29
30 BitmapUploader::BitmapUploader(Window* window, GpuService* gpu_service)
31 : window_(window),
32 gpu_service_(gpu_service),
33 color_(g_transparent_color),
34 width_(0),
35 height_(0),
36 format_(BGRA),
37 next_resource_id_(1u) {}
38
39 BitmapUploader::~BitmapUploader() {
40 }
41
42 void BitmapUploader::Init() {
43 surface_ = window_->RequestSurface(mojom::SurfaceType::DEFAULT);
44 surface_->BindToThread();
45 surface_->set_client(this);
46
47 gles2_context_ = GLES2Context::CreateOffscreenContext(gpu_service_);
48 // CreateOffscreenContext() may return null.
49 }
50
51 // Sets the color which is RGBA.
52 void BitmapUploader::SetColor(uint32_t color) {
53 if (color_ == color)
54 return;
55 color_ = color;
56 if (surface_)
57 Upload();
58 }
59
60 // Sets a bitmap.
61 void BitmapUploader::SetBitmap(int width,
62 int height,
63 std::unique_ptr<std::vector<unsigned char>> data,
64 Format format) {
65 width_ = width;
66 height_ = height;
67 bitmap_ = std::move(data);
68 format_ = format;
69 if (surface_)
70 Upload();
71 }
72
73 void BitmapUploader::Upload() {
74 if (!gles2_context_)
75 return;
76
77 const gfx::Rect bounds(window_->bounds().size());
78
79 cc::CompositorFrame frame;
80 // TODO(rjkroege): Support device scale factors other than 1.
81 frame.metadata.device_scale_factor = 1.0f;
82 frame.delegated_frame_data.reset(new cc::DelegatedFrameData());
83 frame.delegated_frame_data->resource_list.resize(0u);
84
85 const cc::RenderPassId render_pass_id(1, 1);
86 std::unique_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
87 pass->SetAll(render_pass_id, bounds, bounds, gfx::Transform(),
88 true /* has_transparent_background */);
89
90 // The SharedQuadState is owned by the SharedQuadStateList
91 // shared_quad_state_list.
92 cc::SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
93 sqs->SetAll(gfx::Transform(), bounds.size(), bounds, bounds,
94 false /* is_clipped */, 1.f /* opacity */, SkXfermode::kSrc_Mode,
95 0 /* sorting_context_id */);
96
97 if (bitmap_.get()) {
98 gpu::gles2::GLES2Interface* gl = gles2_context_->interface();
99 gfx::Size bitmap_size(width_, height_);
100 GLuint texture_id = BindTextureForSize(bitmap_size);
101 gl->TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap_size.width(),
102 bitmap_size.height(), TextureFormat(), GL_UNSIGNED_BYTE,
103 &((*bitmap_)[0]));
104
105 gpu::Mailbox mailbox;
106 gl->GenMailboxCHROMIUM(mailbox.name);
107 gl->ProduceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
108
109 const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
110 gl->ShallowFlushCHROMIUM();
111
112 gpu::SyncToken sync_token;
113 gl->GenSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
114
115 cc::TransferableResource resource;
116 resource.id = next_resource_id_++;
117 resource_to_texture_id_map_[resource.id] = texture_id;
118 resource.format = cc::ResourceFormat::RGBA_8888;
119 resource.filter = GL_LINEAR;
120 resource.size = bitmap_size;
121 resource.mailbox_holder =
122 gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D);
123 resource.read_lock_fences_enabled = false;
124 resource.is_software = false;
125 resource.is_overlay_candidate = false;
126 frame.delegated_frame_data->resource_list.push_back(std::move(resource));
127
128 cc::TextureDrawQuad* quad =
129 pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
130
131 gfx::Size rect_size;
132 if (width_ <= bounds.width() && height_ <= bounds.height()) {
133 rect_size.SetSize(width_, height_);
134 } else {
135 // The source bitmap is larger than the viewport. Resize it while
136 // maintaining the aspect ratio.
137 float width_ratio = static_cast<float>(width_) / bounds.width();
138 float height_ratio = static_cast<float>(height_) / bounds.height();
139 if (width_ratio > height_ratio) {
140 rect_size.SetSize(bounds.width(), height_ / width_ratio);
141 } else {
142 rect_size.SetSize(width_ / height_ratio, bounds.height());
143 }
144 }
145 gfx::Rect rect(rect_size);
146 const bool needs_blending = true;
147 const bool premultiplied_alpha = true;
148 const gfx::PointF uv_top_left(0.f, 0.f);
149 const gfx::PointF uv_bottom_right(1.f, 1.f);
150 float vertex_opacity[4] = {1.f, 1.f, 1.f, 1.f};
151 const bool y_flipped = false;
152 const bool nearest_neighbor = false;
153 quad->SetAll(sqs, rect, rect, rect, needs_blending, resource.id,
154 gfx::Size(), premultiplied_alpha, uv_top_left, uv_bottom_right,
155 g_transparent_color, vertex_opacity, y_flipped,
156 nearest_neighbor, false);
157 }
158
159 if (color_ != g_transparent_color) {
160 cc::SolidColorDrawQuad* quad =
161 pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
162 const bool force_antialiasing_off = false;
163 const gfx::Rect opaque_rect(0, 0, 0, 0);
164 const bool needs_blending = true;
165 quad->SetAll(sqs, bounds, opaque_rect, bounds, needs_blending, color_,
166 force_antialiasing_off);
167 }
168
169 frame.delegated_frame_data->render_pass_list.push_back(std::move(pass));
170
171 // TODO(rjkroege, fsamuel): We should throttle frames.
172 surface_->SubmitCompositorFrame(std::move(frame), base::Closure());
173 }
174
175 uint32_t BitmapUploader::BindTextureForSize(const gfx::Size& size) {
176 gpu::gles2::GLES2Interface* gl = gles2_context_->interface();
177 // TODO(jamesr): Recycle textures.
178 GLuint texture = 0u;
179 gl->GenTextures(1, &texture);
180 gl->BindTexture(GL_TEXTURE_2D, texture);
181 gl->TexImage2D(GL_TEXTURE_2D, 0, TextureFormat(), size.width(), size.height(),
182 0, TextureFormat(), GL_UNSIGNED_BYTE, 0);
183 gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
184 return texture;
185 }
186
187 void BitmapUploader::OnResourcesReturned(
188 WindowSurface* surface,
189 mojo::Array<cc::ReturnedResource> resources) {
190 gpu::gles2::GLES2Interface* gl = gles2_context_->interface();
191 // TODO(jamesr): Recycle.
192 for (size_t i = 0; i < resources.size(); ++i) {
193 cc::ReturnedResource resource = std::move(resources[i]);
194 DCHECK_EQ(1, resource.count);
195 gl->WaitSyncTokenCHROMIUM(resource.sync_token.GetConstData());
196 uint32_t texture_id = resource_to_texture_id_map_[resource.id];
197 DCHECK_NE(0u, texture_id);
198 resource_to_texture_id_map_.erase(resource.id);
199 gl->DeleteTextures(1, &texture_id);
200 }
201 }
202
203 } // namespace ui
OLDNEW
« no previous file with comments | « services/ui/public/cpp/bitmap_uploader.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698