cc: Use highp precision for texture coords if available and needed
[chromium-blink-merge.git] / cc / resources / resource_provider_unittest.cc
blob68a62612df4d492add3f484c3f90f407ffca6d0d
1 // Copyright 2012 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.
5 #include "cc/resources/resource_provider.h"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "base/logging.h"
11 #include "cc/base/scoped_ptr_deque.h"
12 #include "cc/base/scoped_ptr_hash_map.h"
13 #include "cc/output/output_surface.h"
14 #include "cc/test/fake_output_surface.h"
15 #include "cc/test/test_web_graphics_context_3d.h"
16 #include "gpu/GLES2/gl2extchromium.h"
17 #include "testing/gmock/include/gmock/gmock.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
20 #include "third_party/khronos/GLES2/gl2.h"
21 #include "third_party/khronos/GLES2/gl2ext.h"
22 #include "ui/gfx/rect.h"
24 using testing::Mock;
25 using testing::NiceMock;
26 using testing::Return;
27 using testing::StrictMock;
28 using testing::_;
29 using WebKit::WGC3Dbyte;
30 using WebKit::WGC3Denum;
31 using WebKit::WGC3Dint;
32 using WebKit::WGC3Dsizei;
33 using WebKit::WGC3Duint;
34 using WebKit::WebGLId;
36 namespace cc {
37 namespace {
39 size_t TextureSize(gfx::Size size, WGC3Denum format) {
40 unsigned int components_per_pixel = 4;
41 unsigned int bytes_per_component = 1;
42 return size.width() * size.height() * components_per_pixel *
43 bytes_per_component;
46 struct Texture {
47 Texture() : format(0), filter(GL_NEAREST_MIPMAP_LINEAR) {}
49 void Reallocate(gfx::Size size, WGC3Denum format) {
50 this->size = size;
51 this->format = format;
52 this->data.reset(new uint8_t[TextureSize(size, format)]);
55 gfx::Size size;
56 WGC3Denum format;
57 WGC3Denum filter;
58 scoped_array<uint8_t> data;
61 // Shared data between multiple ResourceProviderContext. This contains mailbox
62 // contents as well as information about sync points.
63 class ContextSharedData {
64 public:
65 static scoped_ptr<ContextSharedData> Create() {
66 return make_scoped_ptr(new ContextSharedData());
69 unsigned InsertSyncPoint() { return next_sync_point_++; }
71 void GenMailbox(WGC3Dbyte* mailbox) {
72 memset(mailbox, 0, sizeof(WGC3Dbyte[64]));
73 memcpy(mailbox, &next_mailbox_, sizeof(next_mailbox_));
74 ++next_mailbox_;
77 void ProduceTexture(const WGC3Dbyte* mailbox_name,
78 unsigned sync_point,
79 scoped_ptr<Texture> texture) {
80 unsigned mailbox = 0;
81 memcpy(&mailbox, mailbox_name, sizeof(mailbox));
82 ASSERT_TRUE(mailbox && mailbox < next_mailbox_);
83 textures_.set(mailbox, texture.Pass());
84 ASSERT_LT(sync_point_for_mailbox_[mailbox], sync_point);
85 sync_point_for_mailbox_[mailbox] = sync_point;
88 scoped_ptr<Texture> ConsumeTexture(const WGC3Dbyte* mailbox_name,
89 unsigned sync_point) {
90 unsigned mailbox = 0;
91 memcpy(&mailbox, mailbox_name, sizeof(mailbox));
92 DCHECK(mailbox && mailbox < next_mailbox_);
94 // If the latest sync point the context has waited on is before the sync
95 // point for when the mailbox was set, pretend we never saw that
96 // ProduceTexture.
97 if (sync_point_for_mailbox_[mailbox] > sync_point) {
98 NOTREACHED();
99 return scoped_ptr<Texture>();
101 return textures_.take(mailbox);
104 private:
105 ContextSharedData() : next_sync_point_(1), next_mailbox_(1) {}
107 unsigned next_sync_point_;
108 unsigned next_mailbox_;
109 typedef ScopedPtrHashMap<unsigned, Texture> TextureMap;
110 TextureMap textures_;
111 base::hash_map<unsigned, unsigned> sync_point_for_mailbox_;
114 class ResourceProviderContext : public TestWebGraphicsContext3D {
115 public:
116 static scoped_ptr<ResourceProviderContext> Create(
117 ContextSharedData* shared_data) {
118 return make_scoped_ptr(
119 new ResourceProviderContext(Attributes(), shared_data));
122 virtual unsigned insertSyncPoint() OVERRIDE {
123 unsigned sync_point = shared_data_->InsertSyncPoint();
124 // Commit the produceTextureCHROMIUM calls at this point, so that
125 // they're associated with the sync point.
126 for (PendingProduceTextureList::iterator it =
127 pending_produce_textures_.begin();
128 it != pending_produce_textures_.end();
129 ++it) {
130 shared_data_->ProduceTexture(
131 (*it)->mailbox, sync_point, (*it)->texture.Pass());
133 pending_produce_textures_.clear();
134 return sync_point;
137 virtual void waitSyncPoint(unsigned sync_point) OVERRIDE {
138 last_waited_sync_point_ = std::max(sync_point, last_waited_sync_point_);
141 virtual void bindTexture(WGC3Denum target, WebGLId texture) OVERRIDE {
142 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
143 ASSERT_TRUE(!texture || textures_.find(texture) != textures_.end());
144 current_texture_ = texture;
147 virtual WebGLId createTexture() OVERRIDE {
148 WebGLId id = TestWebGraphicsContext3D::createTexture();
149 textures_.add(id, make_scoped_ptr(new Texture));
150 return id;
153 virtual void deleteTexture(WebGLId id) OVERRIDE {
154 TextureMap::iterator it = textures_.find(id);
155 ASSERT_FALSE(it == textures_.end());
156 textures_.erase(it);
157 if (current_texture_ == id)
158 current_texture_ = 0;
161 virtual void texStorage2DEXT(WGC3Denum target,
162 WGC3Dint levels,
163 WGC3Duint internalformat,
164 WGC3Dint width,
165 WGC3Dint height) OVERRIDE {
166 ASSERT_TRUE(current_texture_);
167 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
168 ASSERT_EQ(1, levels);
169 WGC3Denum format = GL_RGBA;
170 switch (internalformat) {
171 case GL_RGBA8_OES:
172 break;
173 case GL_BGRA8_EXT:
174 format = GL_BGRA_EXT;
175 break;
176 default:
177 NOTREACHED();
179 AllocateTexture(gfx::Size(width, height), format);
182 virtual void texImage2D(WGC3Denum target,
183 WGC3Dint level,
184 WGC3Denum internalformat,
185 WGC3Dsizei width,
186 WGC3Dsizei height,
187 WGC3Dint border,
188 WGC3Denum format,
189 WGC3Denum type,
190 const void* pixels) OVERRIDE {
191 ASSERT_TRUE(current_texture_);
192 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
193 ASSERT_FALSE(level);
194 ASSERT_EQ(internalformat, format);
195 ASSERT_FALSE(border);
196 ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
197 AllocateTexture(gfx::Size(width, height), format);
198 if (pixels)
199 SetPixels(0, 0, width, height, pixels);
202 virtual void texSubImage2D(WGC3Denum target,
203 WGC3Dint level,
204 WGC3Dint xoffset,
205 WGC3Dint yoffset,
206 WGC3Dsizei width,
207 WGC3Dsizei height,
208 WGC3Denum format,
209 WGC3Denum type,
210 const void* pixels) OVERRIDE {
211 ASSERT_TRUE(current_texture_);
212 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
213 ASSERT_FALSE(level);
214 ASSERT_TRUE(textures_.get(current_texture_));
215 ASSERT_EQ(textures_.get(current_texture_)->format, format);
216 ASSERT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
217 ASSERT_TRUE(pixels);
218 SetPixels(xoffset, yoffset, width, height, pixels);
221 virtual void texParameteri(WGC3Denum target, WGC3Denum param, WGC3Dint value)
222 OVERRIDE {
223 ASSERT_TRUE(current_texture_);
224 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
225 Texture* texture = textures_.get(current_texture_);
226 ASSERT_TRUE(texture);
227 if (param != GL_TEXTURE_MIN_FILTER)
228 return;
229 texture->filter = value;
232 virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox) OVERRIDE {
233 return shared_data_->GenMailbox(mailbox);
236 virtual void produceTextureCHROMIUM(WGC3Denum target,
237 const WGC3Dbyte* mailbox) OVERRIDE {
238 ASSERT_TRUE(current_texture_);
239 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
241 // Delay moving the texture into the mailbox until the next
242 // InsertSyncPoint, so that it is not visible to other contexts that
243 // haven't waited on that sync point.
244 scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
245 memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
246 pending->texture = textures_.take(current_texture_);
247 textures_.set(current_texture_, scoped_ptr<Texture>());
248 pending_produce_textures_.push_back(pending.Pass());
251 virtual void consumeTextureCHROMIUM(WGC3Denum target,
252 const WGC3Dbyte* mailbox) OVERRIDE {
253 ASSERT_TRUE(current_texture_);
254 ASSERT_EQ(static_cast<unsigned>(GL_TEXTURE_2D), target);
255 textures_.set(
256 current_texture_,
257 shared_data_->ConsumeTexture(mailbox, last_waited_sync_point_));
260 void GetPixels(gfx::Size size, WGC3Denum format, uint8_t* pixels) {
261 ASSERT_TRUE(current_texture_);
262 Texture* texture = textures_.get(current_texture_);
263 ASSERT_TRUE(texture);
264 ASSERT_EQ(texture->size, size);
265 ASSERT_EQ(texture->format, format);
266 memcpy(pixels, texture->data.get(), TextureSize(size, format));
269 WGC3Denum GetTextureFilter() {
270 DCHECK(current_texture_);
271 Texture* texture = textures_.get(current_texture_);
272 DCHECK(texture);
273 return texture->filter;
276 int texture_count() { return textures_.size(); }
278 protected:
279 ResourceProviderContext(const Attributes& attrs,
280 ContextSharedData* shared_data)
281 : TestWebGraphicsContext3D(attrs),
282 shared_data_(shared_data),
283 current_texture_(0),
284 last_waited_sync_point_(0) {}
286 private:
287 void AllocateTexture(gfx::Size size, WGC3Denum format) {
288 ASSERT_TRUE(current_texture_);
289 Texture* texture = textures_.get(current_texture_);
290 ASSERT_TRUE(texture);
291 texture->Reallocate(size, format);
294 void SetPixels(int xoffset,
295 int yoffset,
296 int width,
297 int height,
298 const void* pixels) {
299 ASSERT_TRUE(current_texture_);
300 Texture* texture = textures_.get(current_texture_);
301 ASSERT_TRUE(texture);
302 ASSERT_TRUE(texture->data.get());
303 ASSERT_TRUE(xoffset >= 0 && xoffset + width <= texture->size.width());
304 ASSERT_TRUE(yoffset >= 0 && yoffset + height <= texture->size.height());
305 ASSERT_TRUE(pixels);
306 size_t in_pitch = TextureSize(gfx::Size(width, 1), texture->format);
307 size_t out_pitch =
308 TextureSize(gfx::Size(texture->size.width(), 1), texture->format);
309 uint8_t* dest = texture->data.get() + yoffset * out_pitch +
310 TextureSize(gfx::Size(xoffset, 1), texture->format);
311 const uint8_t* src = static_cast<const uint8_t*>(pixels);
312 for (int i = 0; i < height; ++i) {
313 memcpy(dest, src, in_pitch);
314 dest += out_pitch;
315 src += in_pitch;
319 typedef ScopedPtrHashMap<WebGLId, Texture> TextureMap;
320 struct PendingProduceTexture {
321 WGC3Dbyte mailbox[64];
322 scoped_ptr<Texture> texture;
324 typedef ScopedPtrDeque<PendingProduceTexture> PendingProduceTextureList;
325 ContextSharedData* shared_data_;
326 WebGLId current_texture_;
327 TextureMap textures_;
328 unsigned last_waited_sync_point_;
329 PendingProduceTextureList pending_produce_textures_;
332 class ResourceProviderTest
333 : public testing::TestWithParam<ResourceProvider::ResourceType> {
334 public:
335 ResourceProviderTest()
336 : shared_data_(ContextSharedData::Create()),
337 output_surface_(FakeOutputSurface::Create3d(
338 ResourceProviderContext::Create(shared_data_.get())
339 .PassAs<WebKit::WebGraphicsContext3D>())),
340 resource_provider_(ResourceProvider::Create(output_surface_.get(), 0)) {
341 resource_provider_->set_default_resource_type(GetParam());
344 ResourceProviderContext* context() {
345 return static_cast<ResourceProviderContext*>(output_surface_->context3d());
348 void GetResourcePixels(ResourceProvider::ResourceId id,
349 gfx::Size size,
350 WGC3Denum format,
351 uint8_t* pixels) {
352 if (GetParam() == ResourceProvider::GLTexture) {
353 ResourceProvider::ScopedReadLockGL lock_gl(resource_provider_.get(), id);
354 ASSERT_NE(0U, lock_gl.texture_id());
355 context()->bindTexture(GL_TEXTURE_2D, lock_gl.texture_id());
356 context()->GetPixels(size, format, pixels);
357 } else if (GetParam() == ResourceProvider::Bitmap) {
358 ResourceProvider::ScopedReadLockSoftware lock_software(
359 resource_provider_.get(), id);
360 memcpy(pixels,
361 lock_software.sk_bitmap()->getPixels(),
362 lock_software.sk_bitmap()->getSize());
366 void SetResourceFilter(ResourceProvider* resource_provider,
367 ResourceProvider::ResourceId id,
368 WGC3Denum filter) {
369 ResourceProvider::ScopedSamplerGL sampler(
370 resource_provider, id, GL_TEXTURE_2D, filter);
373 WGC3Denum GetResourceFilter(ResourceProvider* resource_provider,
374 ResourceProvider::ResourceId id) {
375 DCHECK_EQ(GetParam(), ResourceProvider::GLTexture);
376 ResourceProvider::ScopedReadLockGL lock_gl(resource_provider, id);
377 EXPECT_NE(0u, lock_gl.texture_id());
378 ResourceProviderContext* context = static_cast<ResourceProviderContext*>(
379 resource_provider->GraphicsContext3D());
380 context->bindTexture(GL_TEXTURE_2D, lock_gl.texture_id());
381 return context->GetTextureFilter();
384 void ExpectNumResources(int count) {
385 EXPECT_EQ(count, static_cast<int>(resource_provider_->num_resources()));
386 if (GetParam() == ResourceProvider::GLTexture)
387 EXPECT_EQ(count, context()->texture_count());
390 protected:
391 scoped_ptr<ContextSharedData> shared_data_;
392 scoped_ptr<OutputSurface> output_surface_;
393 scoped_ptr<ResourceProvider> resource_provider_;
396 TEST_P(ResourceProviderTest, Basic) {
397 gfx::Size size(1, 1);
398 WGC3Denum format = GL_RGBA;
399 size_t pixel_size = TextureSize(size, format);
400 ASSERT_EQ(4U, pixel_size);
402 ResourceProvider::ResourceId id = resource_provider_->CreateResource(
403 size, format, ResourceProvider::TextureUsageAny);
404 ExpectNumResources(1);
406 uint8_t data[4] = { 1, 2, 3, 4 };
407 gfx::Rect rect(size);
408 resource_provider_->SetPixels(id, data, rect, rect, gfx::Vector2d());
410 uint8_t result[4] = { 0 };
411 GetResourcePixels(id, size, format, result);
412 EXPECT_EQ(0, memcmp(data, result, pixel_size));
414 resource_provider_->DeleteResource(id);
415 ExpectNumResources(0);
418 TEST_P(ResourceProviderTest, Upload) {
419 gfx::Size size(2, 2);
420 WGC3Denum format = GL_RGBA;
421 size_t pixel_size = TextureSize(size, format);
422 ASSERT_EQ(16U, pixel_size);
424 ResourceProvider::ResourceId id = resource_provider_->CreateResource(
425 size, format, ResourceProvider::TextureUsageAny);
427 uint8_t image[16] = { 0 };
428 gfx::Rect image_rect(size);
429 resource_provider_->SetPixels(
430 id, image, image_rect, image_rect, gfx::Vector2d());
432 for (uint8_t i = 0; i < pixel_size; ++i)
433 image[i] = i;
435 uint8_t result[16] = { 0 };
437 gfx::Rect source_rect(0, 0, 1, 1);
438 gfx::Vector2d dest_offset(0, 0);
439 resource_provider_->SetPixels(
440 id, image, image_rect, source_rect, dest_offset);
442 uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
443 GetResourcePixels(id, size, format, result);
444 EXPECT_EQ(0, memcmp(expected, result, pixel_size));
447 gfx::Rect source_rect(0, 0, 1, 1);
448 gfx::Vector2d dest_offset(1, 1);
449 resource_provider_->SetPixels(
450 id, image, image_rect, source_rect, dest_offset);
452 uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 };
453 GetResourcePixels(id, size, format, result);
454 EXPECT_EQ(0, memcmp(expected, result, pixel_size));
457 gfx::Rect source_rect(1, 0, 1, 1);
458 gfx::Vector2d dest_offset(0, 1);
459 resource_provider_->SetPixels(
460 id, image, image_rect, source_rect, dest_offset);
462 uint8_t expected[16] = { 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3 };
463 GetResourcePixels(id, size, format, result);
464 EXPECT_EQ(0, memcmp(expected, result, pixel_size));
467 gfx::Rect offset_image_rect(gfx::Point(100, 100), size);
468 gfx::Rect source_rect(100, 100, 1, 1);
469 gfx::Vector2d dest_offset(1, 0);
470 resource_provider_->SetPixels(
471 id, image, offset_image_rect, source_rect, dest_offset);
473 uint8_t expected[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3 };
474 GetResourcePixels(id, size, format, result);
475 EXPECT_EQ(0, memcmp(expected, result, pixel_size));
478 resource_provider_->DeleteResource(id);
481 TEST_P(ResourceProviderTest, TransferResources) {
482 // Resource transfer is only supported with GL textures for now.
483 if (GetParam() != ResourceProvider::GLTexture)
484 return;
486 scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
487 ResourceProviderContext::Create(shared_data_.get())
488 .PassAs<WebKit::WebGraphicsContext3D>()));
489 scoped_ptr<ResourceProvider> child_resource_provider(
490 ResourceProvider::Create(child_output_surface.get(), 0));
492 gfx::Size size(1, 1);
493 WGC3Denum format = GL_RGBA;
494 size_t pixel_size = TextureSize(size, format);
495 ASSERT_EQ(4U, pixel_size);
497 ResourceProvider::ResourceId id1 = child_resource_provider->CreateResource(
498 size, format, ResourceProvider::TextureUsageAny);
499 uint8_t data1[4] = { 1, 2, 3, 4 };
500 gfx::Rect rect(size);
501 child_resource_provider->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
503 ResourceProvider::ResourceId id2 = child_resource_provider->CreateResource(
504 size, format, ResourceProvider::TextureUsageAny);
505 uint8_t data2[4] = { 5, 5, 5, 5 };
506 child_resource_provider->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
508 int child_id = resource_provider_->CreateChild();
510 // Transfer some resources to the parent.
511 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
512 resource_ids_to_transfer.push_back(id1);
513 resource_ids_to_transfer.push_back(id2);
514 TransferableResourceArray list;
515 child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
516 &list);
517 ASSERT_EQ(2u, list.size());
518 EXPECT_NE(0u, list[0].sync_point);
519 EXPECT_NE(0u, list[1].sync_point);
520 EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
521 EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2));
522 resource_provider_->ReceiveFromChild(child_id, list);
525 EXPECT_EQ(2u, resource_provider_->num_resources());
526 ResourceProvider::ResourceIdMap resource_map =
527 resource_provider_->GetChildToParentMap(child_id);
528 ResourceProvider::ResourceId mapped_id1 = resource_map[id1];
529 ResourceProvider::ResourceId mapped_id2 = resource_map[id2];
530 EXPECT_NE(0u, mapped_id1);
531 EXPECT_NE(0u, mapped_id2);
532 EXPECT_FALSE(resource_provider_->InUseByConsumer(id1));
533 EXPECT_FALSE(resource_provider_->InUseByConsumer(id2));
535 uint8_t result[4] = { 0 };
536 GetResourcePixels(mapped_id1, size, format, result);
537 EXPECT_EQ(0, memcmp(data1, result, pixel_size));
539 GetResourcePixels(mapped_id2, size, format, result);
540 EXPECT_EQ(0, memcmp(data2, result, pixel_size));
542 // Check that transfering again the same resource from the child to the
543 // parent is a noop.
544 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
545 resource_ids_to_transfer.push_back(id1);
546 TransferableResourceArray list;
547 child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
548 &list);
549 EXPECT_EQ(0u, list.size());
552 // Transfer resources back from the parent to the child.
553 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
554 resource_ids_to_transfer.push_back(mapped_id1);
555 resource_ids_to_transfer.push_back(mapped_id2);
556 TransferableResourceArray list;
557 resource_provider_->PrepareSendToChild(
558 child_id, resource_ids_to_transfer, &list);
559 ASSERT_EQ(2u, list.size());
560 EXPECT_NE(0u, list[0].sync_point);
561 EXPECT_NE(0u, list[1].sync_point);
562 child_resource_provider->ReceiveFromParent(list);
564 EXPECT_FALSE(child_resource_provider->InUseByConsumer(id1));
565 EXPECT_FALSE(child_resource_provider->InUseByConsumer(id2));
567 ResourceProviderContext* child_context =
568 static_cast<ResourceProviderContext*>(child_output_surface->context3d());
570 ResourceProvider::ScopedReadLockGL lock(child_resource_provider.get(), id1);
571 ASSERT_NE(0U, lock.texture_id());
572 child_context->bindTexture(GL_TEXTURE_2D, lock.texture_id());
573 child_context->GetPixels(size, format, result);
574 EXPECT_EQ(0, memcmp(data1, result, pixel_size));
577 ResourceProvider::ScopedReadLockGL lock(child_resource_provider.get(), id2);
578 ASSERT_NE(0U, lock.texture_id());
579 child_context->bindTexture(GL_TEXTURE_2D, lock.texture_id());
580 child_context->GetPixels(size, format, result);
581 EXPECT_EQ(0, memcmp(data2, result, pixel_size));
584 // Transfer resources to the parent again.
585 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
586 resource_ids_to_transfer.push_back(id1);
587 resource_ids_to_transfer.push_back(id2);
588 TransferableResourceArray list;
589 child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
590 &list);
591 ASSERT_EQ(2u, list.size());
592 EXPECT_NE(0u, list[0].sync_point);
593 EXPECT_NE(0u, list[1].sync_point);
594 EXPECT_TRUE(child_resource_provider->InUseByConsumer(id1));
595 EXPECT_TRUE(child_resource_provider->InUseByConsumer(id2));
596 resource_provider_->ReceiveFromChild(child_id, list);
599 EXPECT_EQ(2u, resource_provider_->num_resources());
600 resource_provider_->DestroyChild(child_id);
601 EXPECT_EQ(0u, resource_provider_->num_resources());
604 TEST_P(ResourceProviderTest, DeleteTransferredResources) {
605 // Resource transfer is only supported with GL textures for now.
606 if (GetParam() != ResourceProvider::GLTexture)
607 return;
609 scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
610 ResourceProviderContext::Create(shared_data_.get())
611 .PassAs<WebKit::WebGraphicsContext3D>()));
612 scoped_ptr<ResourceProvider> child_resource_provider(
613 ResourceProvider::Create(child_output_surface.get(), 0));
615 gfx::Size size(1, 1);
616 WGC3Denum format = GL_RGBA;
617 size_t pixel_size = TextureSize(size, format);
618 ASSERT_EQ(4U, pixel_size);
620 ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
621 size, format, ResourceProvider::TextureUsageAny);
622 uint8_t data[4] = { 1, 2, 3, 4 };
623 gfx::Rect rect(size);
624 child_resource_provider->SetPixels(id, data, rect, rect, gfx::Vector2d());
626 int child_id = resource_provider_->CreateChild();
628 // Transfer some resource to the parent.
629 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
630 resource_ids_to_transfer.push_back(id);
631 TransferableResourceArray list;
632 child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
633 &list);
634 ASSERT_EQ(1u, list.size());
635 EXPECT_NE(0u, list[0].sync_point);
636 EXPECT_TRUE(child_resource_provider->InUseByConsumer(id));
637 resource_provider_->ReceiveFromChild(child_id, list);
640 // Delete textures in the child, while they are transfered.
641 child_resource_provider->DeleteResource(id);
642 EXPECT_EQ(1u, child_resource_provider->num_resources());
644 // Transfer resources back from the parent to the child.
645 ResourceProvider::ResourceIdMap resource_map =
646 resource_provider_->GetChildToParentMap(child_id);
647 ResourceProvider::ResourceId mapped_id = resource_map[id];
648 EXPECT_NE(0u, mapped_id);
649 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
650 resource_ids_to_transfer.push_back(mapped_id);
651 TransferableResourceArray list;
652 resource_provider_->PrepareSendToChild(
653 child_id, resource_ids_to_transfer, &list);
654 ASSERT_EQ(1u, list.size());
655 EXPECT_NE(0u, list[0].sync_point);
656 child_resource_provider->ReceiveFromParent(list);
658 EXPECT_EQ(0u, child_resource_provider->num_resources());
661 TEST_P(ResourceProviderTest, TextureFilters) {
662 // Resource transfer is only supported with GL textures for now.
663 if (GetParam() != ResourceProvider::GLTexture)
664 return;
666 scoped_ptr<OutputSurface> child_output_surface(FakeOutputSurface::Create3d(
667 ResourceProviderContext::Create(shared_data_.get())
668 .PassAs<WebKit::WebGraphicsContext3D>()));
669 scoped_ptr<ResourceProvider> child_resource_provider(
670 ResourceProvider::Create(child_output_surface.get(), 0));
672 gfx::Size size(1, 1);
673 WGC3Denum format = GL_RGBA;
674 size_t pixel_size = TextureSize(size, format);
675 ASSERT_EQ(4U, pixel_size);
677 ResourceProvider::ResourceId id = child_resource_provider->CreateResource(
678 size, format, ResourceProvider::TextureUsageAny);
679 uint8_t data[4] = { 1, 2, 3, 4 };
680 gfx::Rect rect(size);
681 child_resource_provider->SetPixels(id, data, rect, rect, gfx::Vector2d());
682 EXPECT_EQ(static_cast<unsigned>(GL_LINEAR),
683 GetResourceFilter(child_resource_provider.get(), id));
684 SetResourceFilter(child_resource_provider.get(), id, GL_NEAREST);
685 EXPECT_EQ(static_cast<unsigned>(GL_NEAREST),
686 GetResourceFilter(child_resource_provider.get(), id));
688 int child_id = resource_provider_->CreateChild();
690 // Transfer some resource to the parent.
691 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
692 resource_ids_to_transfer.push_back(id);
693 TransferableResourceArray list;
694 child_resource_provider->PrepareSendToParent(resource_ids_to_transfer,
695 &list);
696 ASSERT_EQ(1u, list.size());
697 EXPECT_EQ(static_cast<unsigned>(GL_NEAREST), list[0].filter);
698 resource_provider_->ReceiveFromChild(child_id, list);
700 ResourceProvider::ResourceIdMap resource_map =
701 resource_provider_->GetChildToParentMap(child_id);
702 ResourceProvider::ResourceId mapped_id = resource_map[id];
703 EXPECT_NE(0u, mapped_id);
704 EXPECT_EQ(static_cast<unsigned>(GL_NEAREST),
705 GetResourceFilter(resource_provider_.get(), mapped_id));
706 SetResourceFilter(resource_provider_.get(), mapped_id, GL_LINEAR);
707 EXPECT_EQ(static_cast<unsigned>(GL_LINEAR),
708 GetResourceFilter(resource_provider_.get(), mapped_id));
710 // Transfer resources back from the parent to the child.
711 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
712 resource_ids_to_transfer.push_back(mapped_id);
713 TransferableResourceArray list;
714 resource_provider_->PrepareSendToChild(
715 child_id, resource_ids_to_transfer, &list);
716 ASSERT_EQ(1u, list.size());
717 EXPECT_EQ(static_cast<unsigned>(GL_LINEAR), list[0].filter);
718 child_resource_provider->ReceiveFromParent(list);
720 EXPECT_EQ(static_cast<unsigned>(GL_LINEAR),
721 GetResourceFilter(child_resource_provider.get(), id));
722 SetResourceFilter(child_resource_provider.get(), id, GL_NEAREST);
723 EXPECT_EQ(static_cast<unsigned>(GL_NEAREST),
724 GetResourceFilter(child_resource_provider.get(), id));
727 void ReleaseTextureMailbox(unsigned* release_sync_point, unsigned sync_point) {
728 *release_sync_point = sync_point;
731 TEST_P(ResourceProviderTest, TransferMailboxResources) {
732 // Resource transfer is only supported with GL textures for now.
733 if (GetParam() != ResourceProvider::GLTexture)
734 return;
735 unsigned texture = context()->createTexture();
736 context()->bindTexture(GL_TEXTURE_2D, texture);
737 uint8_t data[4] = { 1, 2, 3, 4 };
738 context()->texImage2D(
739 GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data);
740 gpu::Mailbox mailbox;
741 context()->genMailboxCHROMIUM(mailbox.name);
742 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
743 unsigned sync_point = context()->insertSyncPoint();
745 // All the logic below assumes that the sync points are all positive.
746 EXPECT_LT(0u, sync_point);
748 unsigned release_sync_point = 0;
749 TextureMailbox::ReleaseCallback callback =
750 base::Bind(ReleaseTextureMailbox, &release_sync_point);
751 ResourceProvider::ResourceId resource =
752 resource_provider_->CreateResourceFromTextureMailbox(
753 TextureMailbox(mailbox, callback, sync_point));
754 EXPECT_EQ(1, context()->texture_count());
755 EXPECT_EQ(0u, release_sync_point);
757 // Transfer the resource, expect the sync points to be consistent.
758 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
759 resource_ids_to_transfer.push_back(resource);
760 TransferableResourceArray list;
761 resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
762 ASSERT_EQ(1u, list.size());
763 EXPECT_LE(sync_point, list[0].sync_point);
764 EXPECT_EQ(0,
765 memcmp(mailbox.name, list[0].mailbox.name, sizeof(mailbox.name)));
766 EXPECT_EQ(0u, release_sync_point);
768 context()->waitSyncPoint(list[0].sync_point);
769 unsigned other_texture = context()->createTexture();
770 context()->bindTexture(GL_TEXTURE_2D, other_texture);
771 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
772 uint8_t test_data[4] = { 0 };
773 context()->GetPixels(gfx::Size(1, 1), GL_RGBA, test_data);
774 EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
775 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
776 context()->deleteTexture(other_texture);
777 list[0].sync_point = context()->insertSyncPoint();
778 EXPECT_LT(0u, list[0].sync_point);
780 // Receive the resource, then delete it, expect the sync points to be
781 // consistent.
782 resource_provider_->ReceiveFromParent(list);
783 EXPECT_EQ(1, context()->texture_count());
784 EXPECT_EQ(0u, release_sync_point);
786 resource_provider_->DeleteResource(resource);
787 EXPECT_LE(list[0].sync_point, release_sync_point);
790 // We're going to do the same thing as above, but testing the case where we
791 // delete the resource before we receive it back.
792 sync_point = release_sync_point;
793 EXPECT_LT(0u, sync_point);
794 release_sync_point = 0;
795 resource = resource_provider_->CreateResourceFromTextureMailbox(
796 TextureMailbox(mailbox, callback, sync_point));
797 EXPECT_EQ(1, context()->texture_count());
798 EXPECT_EQ(0u, release_sync_point);
800 // Transfer the resource, expect the sync points to be consistent.
801 ResourceProvider::ResourceIdArray resource_ids_to_transfer;
802 resource_ids_to_transfer.push_back(resource);
803 TransferableResourceArray list;
804 resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list);
805 ASSERT_EQ(1u, list.size());
806 EXPECT_LE(sync_point, list[0].sync_point);
807 EXPECT_EQ(0,
808 memcmp(mailbox.name, list[0].mailbox.name, sizeof(mailbox.name)));
809 EXPECT_EQ(0u, release_sync_point);
811 context()->waitSyncPoint(list[0].sync_point);
812 unsigned other_texture = context()->createTexture();
813 context()->bindTexture(GL_TEXTURE_2D, other_texture);
814 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
815 uint8_t test_data[4] = { 0 };
816 context()->GetPixels(gfx::Size(1, 1), GL_RGBA, test_data);
817 EXPECT_EQ(0, memcmp(data, test_data, sizeof(data)));
818 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
819 context()->deleteTexture(other_texture);
820 list[0].sync_point = context()->insertSyncPoint();
821 EXPECT_LT(0u, list[0].sync_point);
823 // Delete the resource, which shouldn't do anything.
824 resource_provider_->DeleteResource(resource);
825 EXPECT_EQ(1, context()->texture_count());
826 EXPECT_EQ(0u, release_sync_point);
828 // Then receive the resource which should release the mailbox, expect the
829 // sync points to be consistent.
830 resource_provider_->ReceiveFromParent(list);
831 EXPECT_LE(list[0].sync_point, release_sync_point);
834 context()->waitSyncPoint(release_sync_point);
835 context()->bindTexture(GL_TEXTURE_2D, texture);
836 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
837 context()->deleteTexture(texture);
840 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
841 public:
842 MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
843 MOCK_METHOD3(texParameteri,
844 void(WGC3Denum target, WGC3Denum pname, WGC3Dint param));
846 // Force all textures to be "1" so we can test for them.
847 virtual WebKit::WebGLId NextTextureId() OVERRIDE { return 1; }
850 TEST_P(ResourceProviderTest, ScopedSampler) {
851 // Sampling is only supported for GL textures.
852 if (GetParam() != ResourceProvider::GLTexture)
853 return;
855 scoped_ptr<OutputSurface> output_surface(
856 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>(
857 new TextureStateTrackingContext)));
858 TextureStateTrackingContext* context =
859 static_cast<TextureStateTrackingContext*>(output_surface->context3d());
860 scoped_ptr<ResourceProvider> resource_provider(
861 ResourceProvider::Create(output_surface.get(), 0));
863 gfx::Size size(1, 1);
864 WGC3Denum format = GL_RGBA;
865 int texture_id = 1;
867 // Check that the texture gets created with the right sampler settings.
868 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id))
869 .Times(2); // Once to create and once to allocate.
870 EXPECT_CALL(*context,
871 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
872 EXPECT_CALL(*context,
873 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
874 EXPECT_CALL(
875 *context,
876 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
877 EXPECT_CALL(
878 *context,
879 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
880 EXPECT_CALL(*context,
881 texParameteri(GL_TEXTURE_2D,
882 GL_TEXTURE_POOL_CHROMIUM,
883 GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
884 ResourceProvider::ResourceId id = resource_provider->CreateResource(
885 size, format, ResourceProvider::TextureUsageAny);
886 resource_provider->AllocateForTesting(id);
888 // Creating a sampler with the default filter should not change any texture
889 // parameters.
891 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
892 ResourceProvider::ScopedSamplerGL sampler(
893 resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
896 // Using a different filter should be reflected in the texture parameters.
898 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
899 EXPECT_CALL(
900 *context,
901 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
902 EXPECT_CALL(
903 *context,
904 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
905 ResourceProvider::ScopedSamplerGL sampler(
906 resource_provider.get(), id, GL_TEXTURE_2D, GL_NEAREST);
909 // Test resetting to the default filter.
911 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
912 EXPECT_CALL(*context,
913 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
914 EXPECT_CALL(*context,
915 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
916 ResourceProvider::ScopedSamplerGL sampler(
917 resource_provider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
920 Mock::VerifyAndClearExpectations(context);
923 TEST_P(ResourceProviderTest, ManagedResource) {
924 // Sampling is only supported for GL textures.
925 if (GetParam() != ResourceProvider::GLTexture)
926 return;
928 scoped_ptr<OutputSurface> output_surface(
929 FakeOutputSurface::Create3d(scoped_ptr<WebKit::WebGraphicsContext3D>(
930 new TextureStateTrackingContext)));
931 TextureStateTrackingContext* context =
932 static_cast<TextureStateTrackingContext*>(output_surface->context3d());
933 scoped_ptr<ResourceProvider> resource_provider(
934 ResourceProvider::Create(output_surface.get(), 0));
936 gfx::Size size(1, 1);
937 WGC3Denum format = GL_RGBA;
938 int texture_id = 1;
940 // Check that the texture gets created with the right sampler settings.
941 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id));
942 EXPECT_CALL(*context,
943 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
944 EXPECT_CALL(*context,
945 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
946 EXPECT_CALL(
947 *context,
948 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
949 EXPECT_CALL(
950 *context,
951 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
952 EXPECT_CALL(*context,
953 texParameteri(GL_TEXTURE_2D,
954 GL_TEXTURE_POOL_CHROMIUM,
955 GL_TEXTURE_POOL_MANAGED_CHROMIUM));
956 ResourceProvider::ResourceId id = resource_provider->CreateManagedResource(
957 size, format, ResourceProvider::TextureUsageAny);
958 EXPECT_NE(0u, id);
960 Mock::VerifyAndClearExpectations(context);
963 class AllocationTrackingContext3D : public TestWebGraphicsContext3D {
964 public:
965 MOCK_METHOD0(createTexture, WebGLId());
966 MOCK_METHOD1(deleteTexture, void(WebGLId texture_id));
967 MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
968 MOCK_METHOD9(texImage2D,
969 void(WGC3Denum target,
970 WGC3Dint level,
971 WGC3Denum internalformat,
972 WGC3Dsizei width,
973 WGC3Dsizei height,
974 WGC3Dint border,
975 WGC3Denum format,
976 WGC3Denum type,
977 const void* pixels));
978 MOCK_METHOD9(texSubImage2D,
979 void(WGC3Denum target,
980 WGC3Dint level,
981 WGC3Dint xoffset,
982 WGC3Dint yoffset,
983 WGC3Dsizei width,
984 WGC3Dsizei height,
985 WGC3Denum format,
986 WGC3Denum type,
987 const void* pixels));
988 MOCK_METHOD9(asyncTexImage2DCHROMIUM,
989 void(WGC3Denum target,
990 WGC3Dint level,
991 WGC3Denum internalformat,
992 WGC3Dsizei width,
993 WGC3Dsizei height,
994 WGC3Dint border,
995 WGC3Denum format,
996 WGC3Denum type,
997 const void* pixels));
998 MOCK_METHOD9(asyncTexSubImage2DCHROMIUM,
999 void(WGC3Denum target,
1000 WGC3Dint level,
1001 WGC3Dint xoffset,
1002 WGC3Dint yoffset,
1003 WGC3Dsizei width,
1004 WGC3Dsizei height,
1005 WGC3Denum format,
1006 WGC3Denum type,
1007 const void* pixels));
1008 MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(WGC3Denum target));
1011 TEST_P(ResourceProviderTest, TextureAllocation) {
1012 // Only for GL textures.
1013 if (GetParam() != ResourceProvider::GLTexture)
1014 return;
1015 scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
1016 static_cast<WebKit::WebGraphicsContext3D*>(
1017 new NiceMock<AllocationTrackingContext3D>));
1018 scoped_ptr<OutputSurface> output_surface(
1019 FakeOutputSurface::Create3d(mock_context.Pass()));
1021 gfx::Size size(2, 2);
1022 gfx::Vector2d offset(0, 0);
1023 gfx::Rect rect(0, 0, 2, 2);
1024 WGC3Denum format = GL_RGBA;
1025 ResourceProvider::ResourceId id = 0;
1026 uint8_t pixels[16] = { 0 };
1027 int texture_id = 123;
1029 AllocationTrackingContext3D* context =
1030 static_cast<AllocationTrackingContext3D*>(output_surface->context3d());
1031 scoped_ptr<ResourceProvider> resource_provider(
1032 ResourceProvider::Create(output_surface.get(), 0));
1034 // Lazy allocation. Don't allocate when creating the resource.
1035 EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
1036 EXPECT_CALL(*context, deleteTexture(texture_id)).Times(1);
1037 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(1);
1038 EXPECT_CALL(*context, texImage2D(_, _, _, _, _, _, _, _, _)).Times(0);
1039 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, _, _, _, _, _, _))
1040 .Times(0);
1041 id = resource_provider->CreateResource(
1042 size, format, ResourceProvider::TextureUsageAny);
1043 resource_provider->DeleteResource(id);
1044 Mock::VerifyAndClearExpectations(context);
1046 // Do allocate when we set the pixels.
1047 EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
1048 EXPECT_CALL(*context, deleteTexture(texture_id)).Times(1);
1049 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
1050 EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _)).Times(1);
1051 EXPECT_CALL(*context, texSubImage2D(_, _, _, _, 2, 2, _, _, _)).Times(1);
1052 id = resource_provider->CreateResource(
1053 size, format, ResourceProvider::TextureUsageAny);
1054 resource_provider->SetPixels(id, pixels, rect, rect, offset);
1055 resource_provider->DeleteResource(id);
1056 Mock::VerifyAndClearExpectations(context);
1058 // Same for SetPixelsFromBuffer
1059 EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
1060 EXPECT_CALL(*context, deleteTexture(texture_id)).Times(1);
1061 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
1062 EXPECT_CALL(*context, texImage2D(_, _, _, 2, 2, _, _, _, _)).Times(1);
1063 EXPECT_CALL(*context, texSubImage2D(_, _, _, _, 2, 2, _, _, _)).Times(1);
1064 id = resource_provider->CreateResource(
1065 size, format, ResourceProvider::TextureUsageAny);
1066 resource_provider->AcquirePixelBuffer(id);
1067 resource_provider->SetPixelsFromBuffer(id);
1068 resource_provider->ReleasePixelBuffer(id);
1069 resource_provider->DeleteResource(id);
1070 Mock::VerifyAndClearExpectations(context);
1072 // Same for async version.
1073 EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
1074 EXPECT_CALL(*context, deleteTexture(texture_id)).Times(1);
1075 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(2);
1076 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
1077 .Times(1);
1078 id = resource_provider->CreateResource(
1079 size, format, ResourceProvider::TextureUsageAny);
1080 resource_provider->AcquirePixelBuffer(id);
1081 resource_provider->BeginSetPixels(id);
1082 resource_provider->ReleasePixelBuffer(id);
1083 resource_provider->DeleteResource(id);
1084 Mock::VerifyAndClearExpectations(context);
1087 TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) {
1088 // Only for GL textures.
1089 if (GetParam() != ResourceProvider::GLTexture)
1090 return;
1091 scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
1092 static_cast<WebKit::WebGraphicsContext3D*>(
1093 new NiceMock<AllocationTrackingContext3D>));
1094 scoped_ptr<OutputSurface> output_surface(
1095 FakeOutputSurface::Create3d(mock_context.Pass()));
1097 gfx::Size size(2, 2);
1098 WGC3Denum format = GL_RGBA;
1099 ResourceProvider::ResourceId id = 0;
1100 int texture_id = 123;
1102 AllocationTrackingContext3D* context =
1103 static_cast<AllocationTrackingContext3D*>(output_surface->context3d());
1104 scoped_ptr<ResourceProvider> resource_provider(
1105 ResourceProvider::Create(output_surface.get(), 0));
1107 EXPECT_CALL(*context, createTexture()).WillOnce(Return(texture_id));
1108 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(3);
1109 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
1110 .Times(1);
1111 EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
1112 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
1113 id = resource_provider->CreateResource(
1114 size, format, ResourceProvider::TextureUsageAny);
1115 resource_provider->AcquirePixelBuffer(id);
1116 resource_provider->BeginSetPixels(id);
1117 resource_provider->ForceSetPixelsToComplete(id);
1118 resource_provider->ReleasePixelBuffer(id);
1119 Mock::VerifyAndClearExpectations(context);
1122 TEST_P(ResourceProviderTest, AbortForcedAsyncUpload) {
1123 // Only for GL textures.
1124 if (GetParam() != ResourceProvider::GLTexture)
1125 return;
1126 scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
1127 static_cast<WebKit::WebGraphicsContext3D*>(
1128 new NiceMock<AllocationTrackingContext3D>));
1129 scoped_ptr<OutputSurface> output_surface(
1130 FakeOutputSurface::Create3d(mock_context.Pass()));
1132 gfx::Size size(2, 2);
1133 WGC3Denum format = GL_RGBA;
1134 ResourceProvider::ResourceId id = 0;
1135 int texture_id = 123;
1137 AllocationTrackingContext3D* context =
1138 static_cast<AllocationTrackingContext3D*>(output_surface->context3d());
1139 scoped_ptr<ResourceProvider> resource_provider(
1140 ResourceProvider::Create(output_surface.get(), 0));
1142 EXPECT_CALL(*context, createTexture()).WillRepeatedly(Return(texture_id));
1143 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, texture_id)).Times(4);
1144 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_, _, _, 2, 2, _, _, _, _))
1145 .Times(1);
1146 EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
1147 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
1148 EXPECT_CALL(*context, deleteTexture(_)).Times(1);
1149 id = resource_provider->CreateResource(
1150 size, format, ResourceProvider::TextureUsageAny);
1151 resource_provider->AcquirePixelBuffer(id);
1152 resource_provider->BeginSetPixels(id);
1153 resource_provider->ForceSetPixelsToComplete(id);
1154 resource_provider->AbortSetPixels(id);
1155 resource_provider->ReleasePixelBuffer(id);
1156 Mock::VerifyAndClearExpectations(context);
1159 INSTANTIATE_TEST_CASE_P(
1160 ResourceProviderTests,
1161 ResourceProviderTest,
1162 ::testing::Values(ResourceProvider::GLTexture, ResourceProvider::Bitmap));
1164 } // namespace
1165 } // namespace cc