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

Side by Side Diff: components/exo/buffer.cc

Issue 2240503002: exo: Release context provider references when main thread context is lost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: exo: Release context provider references when main thread context is lost. 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 | « components/exo/BUILD.gn ('k') | ui/compositor/test/context_factories_for_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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 "components/exo/buffer.h" 5 #include "components/exo/buffer.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 #include <GLES2/gl2extchromium.h> 9 #include <GLES2/gl2extchromium.h>
10 #include <stdint.h> 10 #include <stdint.h>
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 gles2->GenMailboxCHROMIUM(mailbox->name); 84 gles2->GenMailboxCHROMIUM(mailbox->name);
85 gles2->ProduceTextureCHROMIUM(target, mailbox->name); 85 gles2->ProduceTextureCHROMIUM(target, mailbox->name);
86 } 86 }
87 87
88 } // namespace 88 } // namespace
89 89
90 //////////////////////////////////////////////////////////////////////////////// 90 ////////////////////////////////////////////////////////////////////////////////
91 // Buffer::Texture 91 // Buffer::Texture
92 92
93 // Encapsulates the state and logic needed to bind a buffer to a GLES2 texture. 93 // Encapsulates the state and logic needed to bind a buffer to a GLES2 texture.
94 class Buffer::Texture { 94 class Buffer::Texture : public ui::ContextFactoryObserver {
95 public: 95 public:
96 explicit Texture(cc::ContextProvider* context_provider); 96 Texture(ui::ContextFactory* context_factory,
97 Texture(cc::ContextProvider* context_provider, 97 cc::ContextProvider* context_provider);
98 Texture(ui::ContextFactory* context_factory,
99 cc::ContextProvider* context_provider,
98 gfx::GpuMemoryBuffer* gpu_memory_buffer, 100 gfx::GpuMemoryBuffer* gpu_memory_buffer,
99 unsigned texture_target, 101 unsigned texture_target,
100 unsigned query_type); 102 unsigned query_type);
101 ~Texture(); 103 ~Texture() override;
104
105 // Overridden from ui::ContextFactoryObserver:
106 void OnLostResources() override;
102 107
103 // Returns true if GLES2 resources for texture have been lost. 108 // Returns true if GLES2 resources for texture have been lost.
104 bool IsLost(); 109 bool IsLost();
105 110
106 // Allow texture to be reused after |sync_token| has passed and runs 111 // Allow texture to be reused after |sync_token| has passed and runs
107 // |callback|. 112 // |callback|.
108 void Release(const base::Closure& callback, 113 void Release(const base::Closure& callback,
109 const gpu::SyncToken& sync_token, 114 const gpu::SyncToken& sync_token,
110 bool is_lost); 115 bool is_lost);
111 116
(...skipping 11 matching lines...) Expand all
123 // Copy the contents of texture to |destination| and runs |callback| when 128 // Copy the contents of texture to |destination| and runs |callback| when
124 // completed. Returns a sync token that can be used when accessing texture 129 // completed. Returns a sync token that can be used when accessing texture
125 // from a different context. 130 // from a different context.
126 gpu::SyncToken CopyTexImage(Texture* destination, 131 gpu::SyncToken CopyTexImage(Texture* destination,
127 const base::Closure& callback); 132 const base::Closure& callback);
128 133
129 // Returns the mailbox for this texture. 134 // Returns the mailbox for this texture.
130 gpu::Mailbox mailbox() const { return mailbox_; } 135 gpu::Mailbox mailbox() const { return mailbox_; }
131 136
132 private: 137 private:
138 void DestroyResources();
133 void ReleaseWhenQueryResultIsAvailable(const base::Closure& callback); 139 void ReleaseWhenQueryResultIsAvailable(const base::Closure& callback);
134 void Released(); 140 void Released();
135 void ScheduleWaitForRelease(base::TimeDelta delay); 141 void ScheduleWaitForRelease(base::TimeDelta delay);
136 void WaitForRelease(); 142 void WaitForRelease();
137 143
144 ui::ContextFactory* context_factory_;
138 scoped_refptr<cc::ContextProvider> context_provider_; 145 scoped_refptr<cc::ContextProvider> context_provider_;
139 const unsigned texture_target_; 146 const unsigned texture_target_;
140 const unsigned query_type_; 147 const unsigned query_type_;
141 const GLenum internalformat_; 148 const GLenum internalformat_;
142 unsigned image_id_ = 0; 149 unsigned image_id_ = 0;
143 unsigned query_id_ = 0; 150 unsigned query_id_ = 0;
144 unsigned texture_id_ = 0; 151 unsigned texture_id_ = 0;
145 gpu::Mailbox mailbox_; 152 gpu::Mailbox mailbox_;
146 base::Closure release_callback_; 153 base::Closure release_callback_;
147 base::TimeTicks wait_for_release_time_; 154 base::TimeTicks wait_for_release_time_;
148 bool wait_for_release_pending_ = false; 155 bool wait_for_release_pending_ = false;
149 base::WeakPtrFactory<Texture> weak_ptr_factory_; 156 base::WeakPtrFactory<Texture> weak_ptr_factory_;
150 157
151 DISALLOW_COPY_AND_ASSIGN(Texture); 158 DISALLOW_COPY_AND_ASSIGN(Texture);
152 }; 159 };
153 160
154 Buffer::Texture::Texture(cc::ContextProvider* context_provider) 161 Buffer::Texture::Texture(ui::ContextFactory* context_factory,
155 : context_provider_(context_provider), 162 cc::ContextProvider* context_provider)
163 : context_factory_(context_factory),
164 context_provider_(context_provider),
156 texture_target_(GL_TEXTURE_2D), 165 texture_target_(GL_TEXTURE_2D),
157 query_type_(GL_COMMANDS_COMPLETED_CHROMIUM), 166 query_type_(GL_COMMANDS_COMPLETED_CHROMIUM),
158 internalformat_(GL_RGBA), 167 internalformat_(GL_RGBA),
159 weak_ptr_factory_(this) { 168 weak_ptr_factory_(this) {
160 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 169 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
161 texture_id_ = CreateGLTexture(gles2, texture_target_); 170 texture_id_ = CreateGLTexture(gles2, texture_target_);
162 // Generate a crypto-secure random mailbox name. 171 // Generate a crypto-secure random mailbox name.
163 CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_); 172 CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_);
173 // Provides a notification when |context_provider_| is lost.
174 context_factory_->AddObserver(this);
164 } 175 }
165 176
166 Buffer::Texture::Texture(cc::ContextProvider* context_provider, 177 Buffer::Texture::Texture(ui::ContextFactory* context_factory,
178 cc::ContextProvider* context_provider,
167 gfx::GpuMemoryBuffer* gpu_memory_buffer, 179 gfx::GpuMemoryBuffer* gpu_memory_buffer,
168 unsigned texture_target, 180 unsigned texture_target,
169 unsigned query_type) 181 unsigned query_type)
170 : context_provider_(context_provider), 182 : context_factory_(context_factory),
183 context_provider_(context_provider),
171 texture_target_(texture_target), 184 texture_target_(texture_target),
172 query_type_(query_type), 185 query_type_(query_type),
173 internalformat_(GLInternalFormat(gpu_memory_buffer->GetFormat())), 186 internalformat_(GLInternalFormat(gpu_memory_buffer->GetFormat())),
174 weak_ptr_factory_(this) { 187 weak_ptr_factory_(this) {
175 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 188 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
176 gfx::Size size = gpu_memory_buffer->GetSize(); 189 gfx::Size size = gpu_memory_buffer->GetSize();
177 image_id_ = 190 image_id_ =
178 gles2->CreateImageCHROMIUM(gpu_memory_buffer->AsClientBuffer(), 191 gles2->CreateImageCHROMIUM(gpu_memory_buffer->AsClientBuffer(),
179 size.width(), size.height(), internalformat_); 192 size.width(), size.height(), internalformat_);
180 DLOG_IF(WARNING, !image_id_) << "Failed to create GLImage"; 193 DLOG_IF(WARNING, !image_id_) << "Failed to create GLImage";
181 194
182 gles2->GenQueriesEXT(1, &query_id_); 195 gles2->GenQueriesEXT(1, &query_id_);
183 texture_id_ = CreateGLTexture(gles2, texture_target_); 196 texture_id_ = CreateGLTexture(gles2, texture_target_);
197 // Provides a notification when |context_provider_| is lost.
198 context_factory_->AddObserver(this);
184 } 199 }
185 200
186 Buffer::Texture::~Texture() { 201 Buffer::Texture::~Texture() {
187 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 202 DestroyResources();
188 gles2->DeleteTextures(1, &texture_id_); 203 context_factory_->RemoveObserver(this);
189 if (query_id_) 204 }
190 gles2->DeleteQueriesEXT(1, &query_id_); 205
191 if (image_id_) 206 void Buffer::Texture::OnLostResources() {
192 gles2->DestroyImageCHROMIUM(image_id_); 207 DestroyResources();
208 context_provider_ = nullptr;
193 } 209 }
194 210
195 bool Buffer::Texture::IsLost() { 211 bool Buffer::Texture::IsLost() {
196 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 212 if (context_provider_) {
197 return gles2->GetGraphicsResetStatusKHR() != GL_NO_ERROR; 213 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
214 return gles2->GetGraphicsResetStatusKHR() != GL_NO_ERROR;
215 }
216 return true;
198 } 217 }
199 218
200 void Buffer::Texture::Release(const base::Closure& callback, 219 void Buffer::Texture::Release(const base::Closure& callback,
201 const gpu::SyncToken& sync_token, 220 const gpu::SyncToken& sync_token,
202 bool is_lost) { 221 bool is_lost) {
203 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 222 if (context_provider_) {
204 if (sync_token.HasData()) 223 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
205 gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); 224 if (sync_token.HasData())
225 gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
226 }
206 227
207 // Run callback as texture can be reused immediately after waiting for sync 228 // Run callback as texture can be reused immediately after waiting for sync
208 // token. 229 // token.
209 callback.Run(); 230 callback.Run();
210 } 231 }
211 232
212 gpu::SyncToken Buffer::Texture::BindTexImage() { 233 gpu::SyncToken Buffer::Texture::BindTexImage() {
213 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
214 gles2->ActiveTexture(GL_TEXTURE0);
215 gles2->BindTexture(texture_target_, texture_id_);
216 DCHECK_NE(image_id_, 0u);
217 gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_);
218 // Generate a crypto-secure random mailbox name if not already done.
219 if (mailbox_.IsZero())
220 CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_);
221 // Create and return a sync token that can be used to ensure that the
222 // BindTexImage2DCHROMIUM call is processed before issuing any commands
223 // that will read from the texture on a different context.
224 uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM();
225 gles2->OrderingBarrierCHROMIUM();
226 gpu::SyncToken sync_token; 234 gpu::SyncToken sync_token;
227 gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); 235 if (context_provider_) {
236 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
237 gles2->ActiveTexture(GL_TEXTURE0);
238 gles2->BindTexture(texture_target_, texture_id_);
239 DCHECK_NE(image_id_, 0u);
240 gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_);
241 // Generate a crypto-secure random mailbox name if not already done.
242 if (mailbox_.IsZero())
243 CreateGLTextureMailbox(gles2, texture_id_, texture_target_, &mailbox_);
244 // Create and return a sync token that can be used to ensure that the
245 // BindTexImage2DCHROMIUM call is processed before issuing any commands
246 // that will read from the texture on a different context.
247 uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM();
248 gles2->OrderingBarrierCHROMIUM();
249 gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
250 }
228 return sync_token; 251 return sync_token;
229 } 252 }
230 253
231 void Buffer::Texture::ReleaseTexImage(const base::Closure& callback, 254 void Buffer::Texture::ReleaseTexImage(const base::Closure& callback,
232 const gpu::SyncToken& sync_token, 255 const gpu::SyncToken& sync_token,
233 bool is_lost) { 256 bool is_lost) {
234 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 257 if (context_provider_) {
235 if (sync_token.HasData()) 258 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
236 gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData()); 259 if (sync_token.HasData())
237 gles2->ActiveTexture(GL_TEXTURE0); 260 gles2->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
238 gles2->BindTexture(texture_target_, texture_id_); 261 gles2->ActiveTexture(GL_TEXTURE0);
239 DCHECK_NE(query_id_, 0u); 262 gles2->BindTexture(texture_target_, texture_id_);
240 gles2->BeginQueryEXT(query_type_, query_id_); 263 DCHECK_NE(query_id_, 0u);
241 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_); 264 gles2->BeginQueryEXT(query_type_, query_id_);
242 gles2->EndQueryEXT(query_type_); 265 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_);
243 // Run callback when query result is available and ReleaseTexImage has been 266 gles2->EndQueryEXT(query_type_);
244 // handled if sync token has data and buffer has been used. If buffer was 267 // Run callback when query result is available and ReleaseTexImage has been
245 // never used then run the callback immediately. 268 // handled if sync token has data and buffer has been used. If buffer was
246 if (sync_token.HasData()) { 269 // never used then run the callback immediately.
247 ReleaseWhenQueryResultIsAvailable(callback); 270 if (sync_token.HasData()) {
248 } else { 271 ReleaseWhenQueryResultIsAvailable(callback);
249 callback.Run(); 272 return;
273 }
250 } 274 }
275 callback.Run();
251 } 276 }
252 277
253 gpu::SyncToken Buffer::Texture::CopyTexImage(Texture* destination, 278 gpu::SyncToken Buffer::Texture::CopyTexImage(Texture* destination,
254 const base::Closure& callback) { 279 const base::Closure& callback) {
255 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
256 gles2->ActiveTexture(GL_TEXTURE0);
257 gles2->BindTexture(texture_target_, texture_id_);
258 DCHECK_NE(image_id_, 0u);
259 gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_);
260 gles2->CopyTextureCHROMIUM(texture_id_, destination->texture_id_,
261 internalformat_, GL_UNSIGNED_BYTE, false, false,
262 false);
263 DCHECK_NE(query_id_, 0u);
264 gles2->BeginQueryEXT(query_type_, query_id_);
265 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_);
266 gles2->EndQueryEXT(query_type_);
267 // Run callback when query result is available and ReleaseTexImage has been
268 // handled.
269 ReleaseWhenQueryResultIsAvailable(callback);
270 // Create and return a sync token that can be used to ensure that the
271 // CopyTextureCHROMIUM call is processed before issuing any commands
272 // that will read from the target texture on a different context.
273 uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM();
274 gles2->OrderingBarrierCHROMIUM();
275 gpu::SyncToken sync_token; 280 gpu::SyncToken sync_token;
276 gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData()); 281 if (context_provider_) {
282 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
283 gles2->ActiveTexture(GL_TEXTURE0);
284 gles2->BindTexture(texture_target_, texture_id_);
285 DCHECK_NE(image_id_, 0u);
286 gles2->BindTexImage2DCHROMIUM(texture_target_, image_id_);
287 gles2->CopyTextureCHROMIUM(texture_id_, destination->texture_id_,
288 internalformat_, GL_UNSIGNED_BYTE, false, false,
289 false);
290 DCHECK_NE(query_id_, 0u);
291 gles2->BeginQueryEXT(query_type_, query_id_);
292 gles2->ReleaseTexImage2DCHROMIUM(texture_target_, image_id_);
293 gles2->EndQueryEXT(query_type_);
294 // Run callback when query result is available and ReleaseTexImage has been
295 // handled.
296 ReleaseWhenQueryResultIsAvailable(callback);
297 // Create and return a sync token that can be used to ensure that the
298 // CopyTextureCHROMIUM call is processed before issuing any commands
299 // that will read from the target texture on a different context.
300 uint64_t fence_sync = gles2->InsertFenceSyncCHROMIUM();
301 gles2->OrderingBarrierCHROMIUM();
302 gles2->GenUnverifiedSyncTokenCHROMIUM(fence_sync, sync_token.GetData());
303 }
277 return sync_token; 304 return sync_token;
278 } 305 }
279 306
307 void Buffer::Texture::DestroyResources() {
308 if (context_provider_) {
309 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
310 gles2->DeleteTextures(1, &texture_id_);
311 if (query_id_)
312 gles2->DeleteQueriesEXT(1, &query_id_);
313 if (image_id_)
314 gles2->DestroyImageCHROMIUM(image_id_);
315 }
316 }
317
280 void Buffer::Texture::ReleaseWhenQueryResultIsAvailable( 318 void Buffer::Texture::ReleaseWhenQueryResultIsAvailable(
281 const base::Closure& callback) { 319 const base::Closure& callback) {
320 DCHECK(context_provider_);
282 DCHECK(release_callback_.is_null()); 321 DCHECK(release_callback_.is_null());
283 release_callback_ = callback; 322 release_callback_ = callback;
284 base::TimeDelta wait_for_release_delay = 323 base::TimeDelta wait_for_release_delay =
285 base::TimeDelta::FromMilliseconds(kWaitForReleaseDelayMs); 324 base::TimeDelta::FromMilliseconds(kWaitForReleaseDelayMs);
286 wait_for_release_time_ = base::TimeTicks::Now() + wait_for_release_delay; 325 wait_for_release_time_ = base::TimeTicks::Now() + wait_for_release_delay;
287 ScheduleWaitForRelease(wait_for_release_delay); 326 ScheduleWaitForRelease(wait_for_release_delay);
288 context_provider_->ContextSupport()->SignalQuery( 327 context_provider_->ContextSupport()->SignalQuery(
289 query_id_, 328 query_id_,
290 base::Bind(&Buffer::Texture::Released, weak_ptr_factory_.GetWeakPtr())); 329 base::Bind(&Buffer::Texture::Released, weak_ptr_factory_.GetWeakPtr()));
291 } 330 }
(...skipping 22 matching lines...) Expand all
314 return; 353 return;
315 354
316 base::TimeTicks current_time = base::TimeTicks::Now(); 355 base::TimeTicks current_time = base::TimeTicks::Now();
317 if (current_time < wait_for_release_time_) { 356 if (current_time < wait_for_release_time_) {
318 ScheduleWaitForRelease(wait_for_release_time_ - current_time); 357 ScheduleWaitForRelease(wait_for_release_time_ - current_time);
319 return; 358 return;
320 } 359 }
321 360
322 base::Closure callback = base::ResetAndReturn(&release_callback_); 361 base::Closure callback = base::ResetAndReturn(&release_callback_);
323 362
324 { 363 if (context_provider_) {
325 TRACE_EVENT0("exo", "Buffer::Texture::WaitForQueryResult"); 364 TRACE_EVENT0("exo", "Buffer::Texture::WaitForQueryResult");
326 365
327 // We need to wait for the result to be available. Getting the result of 366 // We need to wait for the result to be available. Getting the result of
328 // the query implies waiting for it to become available. The actual result 367 // the query implies waiting for it to become available. The actual result
329 // is unimportant and also not well defined. 368 // is unimportant and also not well defined.
330 unsigned result = 0; 369 unsigned result = 0;
331 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL(); 370 gpu::gles2::GLES2Interface* gles2 = context_provider_->ContextGL();
332 gles2->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &result); 371 gles2->GetQueryObjectuivEXT(query_id_, GL_QUERY_RESULT_EXT, &result);
333 } 372 }
334 373
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 417
379 // Increment the use count for this buffer. 418 // Increment the use count for this buffer.
380 ++use_count_; 419 ++use_count_;
381 420
382 // If textures are lost, destroy them to ensure that we create new ones below. 421 // If textures are lost, destroy them to ensure that we create new ones below.
383 if (contents_texture_ && contents_texture_->IsLost()) 422 if (contents_texture_ && contents_texture_->IsLost())
384 contents_texture_.reset(); 423 contents_texture_.reset();
385 if (texture_ && texture_->IsLost()) 424 if (texture_ && texture_->IsLost())
386 texture_.reset(); 425 texture_.reset();
387 426
427 ui::ContextFactory* context_factory =
428 aura::Env::GetInstance()->context_factory();
388 // Note: This can fail if GPU acceleration has been disabled. 429 // Note: This can fail if GPU acceleration has been disabled.
389 scoped_refptr<cc::ContextProvider> context_provider = 430 scoped_refptr<cc::ContextProvider> context_provider =
390 aura::Env::GetInstance() 431 context_factory->SharedMainThreadContextProvider();
391 ->context_factory()
392 ->SharedMainThreadContextProvider();
393 if (!context_provider) { 432 if (!context_provider) {
394 DLOG(WARNING) << "Failed to acquire a context provider"; 433 DLOG(WARNING) << "Failed to acquire a context provider";
395 Release(); // Decrements the use count 434 Release(); // Decrements the use count
396 return nullptr; 435 return nullptr;
397 } 436 }
398 437
399 // Create a new image texture for |gpu_memory_buffer_| with |texture_target_| 438 // Create a new image texture for |gpu_memory_buffer_| with |texture_target_|
400 // if one doesn't already exist. The contents of this buffer are copied to 439 // if one doesn't already exist. The contents of this buffer are copied to
401 // |texture| using a call to CopyTexImage. 440 // |texture| using a call to CopyTexImage.
402 if (!contents_texture_) { 441 if (!contents_texture_) {
403 contents_texture_ = base::WrapUnique( 442 contents_texture_ = base::WrapUnique(
404 new Texture(context_provider.get(), gpu_memory_buffer_.get(), 443 new Texture(context_factory, context_provider.get(),
405 texture_target_, query_type_)); 444 gpu_memory_buffer_.get(), texture_target_, query_type_));
406 } 445 }
407 446
408 if (use_zero_copy_) { 447 if (use_zero_copy_) {
409 // Zero-copy means using the contents texture directly. 448 // Zero-copy means using the contents texture directly.
410 Texture* texture = contents_texture_.get(); 449 Texture* texture = contents_texture_.get();
411 450
412 // This binds the latest contents of this buffer to |texture|. 451 // This binds the latest contents of this buffer to |texture|.
413 gpu::SyncToken sync_token = texture->BindTexImage(); 452 gpu::SyncToken sync_token = texture->BindTexImage();
414 453
415 *texture_mailbox = 454 *texture_mailbox =
416 cc::TextureMailbox(texture->mailbox(), sync_token, texture_target_, 455 cc::TextureMailbox(texture->mailbox(), sync_token, texture_target_,
417 gpu_memory_buffer_->GetSize(), is_overlay_candidate_, 456 gpu_memory_buffer_->GetSize(), is_overlay_candidate_,
418 secure_output_only); 457 secure_output_only);
419 // The contents texture will be released when no longer used by the 458 // The contents texture will be released when no longer used by the
420 // compositor. 459 // compositor.
421 return cc::SingleReleaseCallback::Create( 460 return cc::SingleReleaseCallback::Create(
422 base::Bind(&Buffer::Texture::ReleaseTexImage, base::Unretained(texture), 461 base::Bind(&Buffer::Texture::ReleaseTexImage, base::Unretained(texture),
423 base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(), 462 base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(),
424 base::Passed(&contents_texture_)))); 463 base::Passed(&contents_texture_))));
425 } 464 }
426 465
427 // Create a mailbox texture that we copy the buffer contents to. 466 // Create a mailbox texture that we copy the buffer contents to.
428 if (!texture_) 467 if (!texture_) {
429 texture_ = base::WrapUnique(new Texture(context_provider.get())); 468 texture_ =
469 base::WrapUnique(new Texture(context_factory, context_provider.get()));
470 }
430 471
431 // Copy the contents of |contents_texture| to |texture| and produce a 472 // Copy the contents of |contents_texture| to |texture| and produce a
432 // texture mailbox from the result in |texture|. 473 // texture mailbox from the result in |texture|.
433 Texture* contents_texture = contents_texture_.get(); 474 Texture* contents_texture = contents_texture_.get();
434 Texture* texture = texture_.get(); 475 Texture* texture = texture_.get();
435 476
436 // The contents texture will be released when copy has completed. 477 // The contents texture will be released when copy has completed.
437 gpu::SyncToken sync_token = contents_texture->CopyTexImage( 478 gpu::SyncToken sync_token = contents_texture->CopyTexImage(
438 texture, base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(), 479 texture, base::Bind(&Buffer::ReleaseContentsTexture, AsWeakPtr(),
439 base::Passed(&contents_texture_))); 480 base::Passed(&contents_texture_)));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 } 540 }
500 541
501 void Buffer::ReleaseContentsTexture(std::unique_ptr<Texture> texture) { 542 void Buffer::ReleaseContentsTexture(std::unique_ptr<Texture> texture) {
502 TRACE_EVENT0("exo", "Buffer::ReleaseContentsTexture"); 543 TRACE_EVENT0("exo", "Buffer::ReleaseContentsTexture");
503 544
504 contents_texture_ = std::move(texture); 545 contents_texture_ = std::move(texture);
505 Release(); 546 Release();
506 } 547 }
507 548
508 } // namespace exo 549 } // namespace exo
OLDNEW
« no previous file with comments | « components/exo/BUILD.gn ('k') | ui/compositor/test/context_factories_for_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698