Depend on stored sync session GUID for Android.
[chromium-blink-merge.git] / cc / resource_provider_unittest.cc
blob71912b30d055f14a322f8c1c7c795ba74d6dd5c4
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/resource_provider.h"
7 #include "base/logging.h"
8 #include "cc/graphics_context.h"
9 #include "cc/scoped_ptr_deque.h"
10 #include "cc/scoped_ptr_hash_map.h"
11 #include "cc/test/compositor_fake_web_graphics_context_3d.h"
12 #include "cc/test/fake_web_compositor_output_surface.h"
13 #include "testing/gmock/include/gmock/gmock.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "third_party/khronos/GLES2/gl2.h"
16 #include "third_party/khronos/GLES2/gl2ext.h"
17 #include "ui/gfx/rect.h"
18 #include <public/WebGraphicsContext3D.h>
20 using namespace WebKit;
22 using testing::Mock;
24 namespace cc {
25 namespace {
27 size_t textureSize(const gfx::Size& size, WGC3Denum format)
29 unsigned int componentsPerPixel = 4;
30 unsigned int bytesPerComponent = 1;
31 return size.width() * size.height() * componentsPerPixel * bytesPerComponent;
34 struct Texture {
35 Texture(const gfx::Size& size, WGC3Denum format)
36 : size(size)
37 , format(format)
38 , data(new uint8_t[textureSize(size, format)])
42 gfx::Size size;
43 WGC3Denum format;
44 scoped_array<uint8_t> data;
47 // Shared data between multiple ResourceProviderContext. This contains mailbox
48 // contents as well as information about sync points.
49 class ContextSharedData {
50 public:
51 static scoped_ptr<ContextSharedData> create() { return make_scoped_ptr(new ContextSharedData()); }
53 unsigned insertSyncPoint() { return m_nextSyncPoint++; }
55 void genMailbox(WGC3Dbyte* mailbox)
57 memset(mailbox, 0, sizeof(WGC3Dbyte[64]));
58 memcpy(mailbox, &m_nextMailBox, sizeof(m_nextMailBox));
59 ++m_nextMailBox;
62 void produceTexture(const WGC3Dbyte* mailboxName, unsigned syncPoint, scoped_ptr<Texture> texture)
64 unsigned mailbox = 0;
65 memcpy(&mailbox, mailboxName, sizeof(mailbox));
66 ASSERT_TRUE(mailbox && mailbox < m_nextMailBox);
67 m_textures.set(mailbox, texture.Pass());
68 ASSERT_LT(m_syncPointForMailbox[mailbox], syncPoint);
69 m_syncPointForMailbox[mailbox] = syncPoint;
72 scoped_ptr<Texture> consumeTexture(const WGC3Dbyte* mailboxName, unsigned syncPoint)
74 unsigned mailbox = 0;
75 memcpy(&mailbox, mailboxName, sizeof(mailbox));
76 DCHECK(mailbox && mailbox < m_nextMailBox);
78 // If the latest sync point the context has waited on is before the sync
79 // point for when the mailbox was set, pretend we never saw that
80 // produceTexture.
81 if (m_syncPointForMailbox[mailbox] < syncPoint)
82 return scoped_ptr<Texture>();
83 return m_textures.take(mailbox);
86 private:
87 ContextSharedData()
88 : m_nextSyncPoint(1)
89 , m_nextMailBox(1)
90 { }
92 unsigned m_nextSyncPoint;
93 unsigned m_nextMailBox;
94 typedef ScopedPtrHashMap<unsigned, Texture> TextureMap;
95 TextureMap m_textures;
96 base::hash_map<unsigned, unsigned> m_syncPointForMailbox;
99 class ResourceProviderContext : public CompositorFakeWebGraphicsContext3D {
100 public:
101 static scoped_ptr<ResourceProviderContext> create(ContextSharedData* sharedData) { return make_scoped_ptr(new ResourceProviderContext(Attributes(), sharedData)); }
103 virtual unsigned insertSyncPoint()
105 unsigned syncPoint = m_sharedData->insertSyncPoint();
106 // Commit the produceTextureCHROMIUM calls at this point, so that
107 // they're associated with the sync point.
108 for (PendingProduceTextureList::iterator it = m_pendingProduceTextures.begin(); it != m_pendingProduceTextures.end(); ++it)
109 m_sharedData->produceTexture((*it)->mailbox, syncPoint, (*it)->texture.Pass());
110 m_pendingProduceTextures.clear();
111 return syncPoint;
114 virtual void waitSyncPoint(unsigned syncPoint)
116 m_lastWaitedSyncPoint = std::max(syncPoint, m_lastWaitedSyncPoint);
119 virtual void bindTexture(WGC3Denum target, WebGLId texture)
121 ASSERT_EQ(target, GL_TEXTURE_2D);
122 ASSERT_TRUE(!texture || m_textures.find(texture) != m_textures.end());
123 m_currentTexture = texture;
126 virtual WebGLId createTexture()
128 WebGLId id = CompositorFakeWebGraphicsContext3D::createTexture();
129 m_textures.add(id, scoped_ptr<Texture>());
130 return id;
133 virtual void deleteTexture(WebGLId id)
135 TextureMap::iterator it = m_textures.find(id);
136 ASSERT_FALSE(it == m_textures.end());
137 m_textures.erase(it);
138 if (m_currentTexture == id)
139 m_currentTexture = 0;
142 virtual void texStorage2DEXT(WGC3Denum target, WGC3Dint levels, WGC3Duint internalformat,
143 WGC3Dint width, WGC3Dint height)
145 ASSERT_TRUE(m_currentTexture);
146 ASSERT_EQ(target, GL_TEXTURE_2D);
147 ASSERT_EQ(levels, 1);
148 WGC3Denum format = GL_RGBA;
149 switch (internalformat) {
150 case GL_RGBA8_OES:
151 break;
152 case GL_BGRA8_EXT:
153 format = GL_BGRA_EXT;
154 break;
155 default:
156 NOTREACHED();
158 allocateTexture(gfx::Size(width, height), format);
161 virtual void texImage2D(WGC3Denum target, WGC3Dint level, WGC3Denum internalformat, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format, WGC3Denum type, const void* pixels)
163 ASSERT_TRUE(m_currentTexture);
164 ASSERT_EQ(target, GL_TEXTURE_2D);
165 ASSERT_FALSE(level);
166 ASSERT_EQ(internalformat, format);
167 ASSERT_FALSE(border);
168 ASSERT_EQ(type, GL_UNSIGNED_BYTE);
169 allocateTexture(gfx::Size(width, height), format);
170 if (pixels)
171 setPixels(0, 0, width, height, pixels);
174 virtual void texSubImage2D(WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, const void* pixels)
176 ASSERT_TRUE(m_currentTexture);
177 ASSERT_EQ(target, GL_TEXTURE_2D);
178 ASSERT_FALSE(level);
179 ASSERT_TRUE(m_textures.get(m_currentTexture));
180 ASSERT_EQ(m_textures.get(m_currentTexture)->format, format);
181 ASSERT_EQ(type, GL_UNSIGNED_BYTE);
182 ASSERT_TRUE(pixels);
183 setPixels(xoffset, yoffset, width, height, pixels);
186 virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox) { return m_sharedData->genMailbox(mailbox); }
187 virtual void produceTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailbox)
189 ASSERT_TRUE(m_currentTexture);
190 ASSERT_EQ(target, GL_TEXTURE_2D);
192 // Delay moving the texture into the mailbox until the next
193 // insertSyncPoint, so that it is not visible to other contexts that
194 // haven't waited on that sync point.
195 scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
196 memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
197 pending->texture = m_textures.take(m_currentTexture);
198 m_textures.set(m_currentTexture, scoped_ptr<Texture>());
199 m_pendingProduceTextures.append(pending.Pass());
202 virtual void consumeTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailbox)
204 ASSERT_TRUE(m_currentTexture);
205 ASSERT_EQ(target, GL_TEXTURE_2D);
206 m_textures.set(m_currentTexture, m_sharedData->consumeTexture(mailbox, m_lastWaitedSyncPoint));
209 void getPixels(const gfx::Size& size, WGC3Denum format, uint8_t* pixels)
211 ASSERT_TRUE(m_currentTexture);
212 Texture* texture = m_textures.get(m_currentTexture);
213 ASSERT_TRUE(texture);
214 ASSERT_EQ(texture->size, size);
215 ASSERT_EQ(texture->format, format);
216 memcpy(pixels, texture->data.get(), textureSize(size, format));
219 int textureCount()
221 return m_textures.size();
224 protected:
225 ResourceProviderContext(const Attributes& attrs, ContextSharedData* sharedData)
226 : CompositorFakeWebGraphicsContext3D(attrs)
227 , m_sharedData(sharedData)
228 , m_currentTexture(0)
229 , m_lastWaitedSyncPoint(0)
232 private:
233 void allocateTexture(const gfx::Size& size, WGC3Denum format)
235 ASSERT_TRUE(m_currentTexture);
236 m_textures.set(m_currentTexture, make_scoped_ptr(new Texture(size, format)));
239 void setPixels(int xoffset, int yoffset, int width, int height, const void* pixels)
241 ASSERT_TRUE(m_currentTexture);
242 Texture* texture = m_textures.get(m_currentTexture);
243 ASSERT_TRUE(texture);
244 ASSERT_TRUE(xoffset >= 0 && xoffset+width <= texture->size.width());
245 ASSERT_TRUE(yoffset >= 0 && yoffset+height <= texture->size.height());
246 ASSERT_TRUE(pixels);
247 size_t inPitch = textureSize(gfx::Size(width, 1), texture->format);
248 size_t outPitch = textureSize(gfx::Size(texture->size.width(), 1), texture->format);
249 uint8_t* dest = texture->data.get() + yoffset * outPitch + textureSize(gfx::Size(xoffset, 1), texture->format);
250 const uint8_t* src = static_cast<const uint8_t*>(pixels);
251 for (int i = 0; i < height; ++i) {
252 memcpy(dest, src, inPitch);
253 dest += outPitch;
254 src += inPitch;
258 typedef ScopedPtrHashMap<WebGLId, Texture> TextureMap;
259 struct PendingProduceTexture {
260 WGC3Dbyte mailbox[64];
261 scoped_ptr<Texture> texture;
263 typedef ScopedPtrDeque<PendingProduceTexture> PendingProduceTextureList;
264 ContextSharedData* m_sharedData;
265 WebGLId m_currentTexture;
266 TextureMap m_textures;
267 unsigned m_lastWaitedSyncPoint;
268 PendingProduceTextureList m_pendingProduceTextures;
271 class ResourceProviderTest : public testing::TestWithParam<ResourceProvider::ResourceType> {
272 public:
273 ResourceProviderTest()
274 : m_sharedData(ContextSharedData::create())
275 , m_context(FakeWebCompositorOutputSurface::create(ResourceProviderContext::create(m_sharedData.get()).PassAs<WebKit::WebGraphicsContext3D>().PassAs<WebKit::WebGraphicsContext3D>()))
276 , m_resourceProvider(ResourceProvider::create(m_context.get()))
278 m_resourceProvider->setDefaultResourceType(GetParam());
281 ResourceProviderContext* context() { return static_cast<ResourceProviderContext*>(m_context->context3D()); }
283 void getResourcePixels(ResourceProvider::ResourceId id, const gfx::Size& size, WGC3Denum format, uint8_t* pixels)
285 if (GetParam() == ResourceProvider::GLTexture) {
286 ResourceProvider::ScopedReadLockGL lockGL(m_resourceProvider.get(), id);
287 ASSERT_NE(0U, lockGL.textureId());
288 context()->bindTexture(GL_TEXTURE_2D, lockGL.textureId());
289 context()->getPixels(size, format, pixels);
290 } else if (GetParam() == ResourceProvider::Bitmap) {
291 ResourceProvider::ScopedReadLockSoftware lockSoftware(m_resourceProvider.get(), id);
292 memcpy(pixels, lockSoftware.skBitmap()->getPixels(), lockSoftware.skBitmap()->getSize());
296 void expectNumResources(int count)
298 EXPECT_EQ(count, static_cast<int>(m_resourceProvider->numResources()));
299 if (GetParam() == ResourceProvider::GLTexture)
300 EXPECT_EQ(count, context()->textureCount());
303 protected:
304 scoped_ptr<ContextSharedData> m_sharedData;
305 scoped_ptr<GraphicsContext> m_context;
306 scoped_ptr<ResourceProvider> m_resourceProvider;
309 TEST_P(ResourceProviderTest, Basic)
311 gfx::Size size(1, 1);
312 WGC3Denum format = GL_RGBA;
313 int pool = 1;
314 size_t pixelSize = textureSize(size, format);
315 ASSERT_EQ(4U, pixelSize);
317 ResourceProvider::ResourceId id = m_resourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
318 expectNumResources(1);
320 uint8_t data[4] = {1, 2, 3, 4};
321 gfx::Rect rect(gfx::Point(), size);
322 m_resourceProvider->setPixels(id, data, rect, rect, gfx::Vector2d());
324 uint8_t result[4] = {0};
325 getResourcePixels(id, size, format, result);
326 EXPECT_EQ(0, memcmp(data, result, pixelSize));
328 m_resourceProvider->deleteResource(id);
329 expectNumResources(0);
332 TEST_P(ResourceProviderTest, DeleteOwnedResources)
334 gfx::Size size(1, 1);
335 WGC3Denum format = GL_RGBA;
336 int pool = 1;
338 const int count = 3;
339 for (int i = 0; i < count; ++i)
340 m_resourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
341 expectNumResources(3);
343 m_resourceProvider->deleteOwnedResources(pool+1);
344 expectNumResources(3);
346 m_resourceProvider->deleteOwnedResources(pool);
347 expectNumResources(0);
350 TEST_P(ResourceProviderTest, Upload)
352 gfx::Size size(2, 2);
353 WGC3Denum format = GL_RGBA;
354 int pool = 1;
355 size_t pixelSize = textureSize(size, format);
356 ASSERT_EQ(16U, pixelSize);
358 ResourceProvider::ResourceId id = m_resourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
360 uint8_t image[16] = {0};
361 gfx::Rect imageRect(gfx::Point(), size);
362 m_resourceProvider->setPixels(id, image, imageRect, imageRect, gfx::Vector2d());
364 for (uint8_t i = 0 ; i < pixelSize; ++i)
365 image[i] = i;
367 uint8_t result[16] = {0};
369 gfx::Rect sourceRect(0, 0, 1, 1);
370 gfx::Vector2d destOffset(0, 0);
371 m_resourceProvider->setPixels(id, image, imageRect, sourceRect, destOffset);
373 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0,
374 0, 0, 0, 0, 0, 0, 0, 0};
375 getResourcePixels(id, size, format, result);
376 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
379 gfx::Rect sourceRect(0, 0, 1, 1);
380 gfx::Vector2d destOffset(1, 1);
381 m_resourceProvider->setPixels(id, image, imageRect, sourceRect, destOffset);
383 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0,
384 0, 0, 0, 0, 0, 1, 2, 3};
385 getResourcePixels(id, size, format, result);
386 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
389 gfx::Rect sourceRect(1, 0, 1, 1);
390 gfx::Vector2d destOffset(0, 1);
391 m_resourceProvider->setPixels(id, image, imageRect, sourceRect, destOffset);
393 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0,
394 4, 5, 6, 7, 0, 1, 2, 3};
395 getResourcePixels(id, size, format, result);
396 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
399 gfx::Rect offsetImageRect(gfx::Point(100, 100), size);
400 gfx::Rect sourceRect(100, 100, 1, 1);
401 gfx::Vector2d destOffset(1, 0);
402 m_resourceProvider->setPixels(id, image, offsetImageRect, sourceRect, destOffset);
404 uint8_t expected[16] = {0, 1, 2, 3, 0, 1, 2, 3,
405 4, 5, 6, 7, 0, 1, 2, 3};
406 getResourcePixels(id, size, format, result);
407 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
411 m_resourceProvider->deleteResource(id);
414 TEST_P(ResourceProviderTest, TransferResources)
416 // Resource transfer is only supported with GL textures for now.
417 if (GetParam() != ResourceProvider::GLTexture)
418 return;
420 scoped_ptr<GraphicsContext> childContext(FakeWebCompositorOutputSurface::create(ResourceProviderContext::create(m_sharedData.get()).PassAs<WebKit::WebGraphicsContext3D>()));
421 scoped_ptr<ResourceProvider> childResourceProvider(ResourceProvider::create(childContext.get()));
423 gfx::Size size(1, 1);
424 WGC3Denum format = GL_RGBA;
425 int pool = 1;
426 size_t pixelSize = textureSize(size, format);
427 ASSERT_EQ(4U, pixelSize);
429 ResourceProvider::ResourceId id1 = childResourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
430 uint8_t data1[4] = {1, 2, 3, 4};
431 gfx::Rect rect(gfx::Point(), size);
432 childResourceProvider->setPixels(id1, data1, rect, rect, gfx::Vector2d());
434 ResourceProvider::ResourceId id2 = childResourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
435 uint8_t data2[4] = {5, 5, 5, 5};
436 childResourceProvider->setPixels(id2, data2, rect, rect, gfx::Vector2d());
438 int childPool = 2;
439 int childId = m_resourceProvider->createChild(childPool);
442 // Transfer some resources to the parent.
443 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
444 resourceIdsToTransfer.push_back(id1);
445 resourceIdsToTransfer.push_back(id2);
446 TransferableResourceList list;
447 childResourceProvider->prepareSendToParent(resourceIdsToTransfer, &list);
448 EXPECT_NE(0u, list.sync_point);
449 EXPECT_EQ(2u, list.resources.size());
450 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id1));
451 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id2));
452 m_resourceProvider->receiveFromChild(childId, list);
455 EXPECT_EQ(2u, m_resourceProvider->numResources());
456 ResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->getChildToParentMap(childId);
457 ResourceProvider::ResourceId mappedId1 = resourceMap[id1];
458 ResourceProvider::ResourceId mappedId2 = resourceMap[id2];
459 EXPECT_NE(0u, mappedId1);
460 EXPECT_NE(0u, mappedId2);
461 EXPECT_FALSE(m_resourceProvider->inUseByConsumer(id1));
462 EXPECT_FALSE(m_resourceProvider->inUseByConsumer(id2));
464 uint8_t result[4] = {0};
465 getResourcePixels(mappedId1, size, format, result);
466 EXPECT_EQ(0, memcmp(data1, result, pixelSize));
468 getResourcePixels(mappedId2, size, format, result);
469 EXPECT_EQ(0, memcmp(data2, result, pixelSize));
472 // Check that transfering again the same resource from the child to the
473 // parent is a noop.
474 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
475 resourceIdsToTransfer.push_back(id1);
476 TransferableResourceList list;
477 childResourceProvider->prepareSendToParent(resourceIdsToTransfer, &list);
478 EXPECT_EQ(0u, list.sync_point);
479 EXPECT_EQ(0u, list.resources.size());
483 // Transfer resources back from the parent to the child.
484 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
485 resourceIdsToTransfer.push_back(mappedId1);
486 resourceIdsToTransfer.push_back(mappedId2);
487 TransferableResourceList list;
488 m_resourceProvider->prepareSendToChild(childId, resourceIdsToTransfer, &list);
489 EXPECT_NE(0u, list.sync_point);
490 EXPECT_EQ(2u, list.resources.size());
491 childResourceProvider->receiveFromParent(list);
493 EXPECT_FALSE(childResourceProvider->inUseByConsumer(id1));
494 EXPECT_FALSE(childResourceProvider->inUseByConsumer(id2));
496 ResourceProviderContext* childContext3D = static_cast<ResourceProviderContext*>(childContext->context3D());
498 ResourceProvider::ScopedReadLockGL lock(childResourceProvider.get(), id1);
499 ASSERT_NE(0U, lock.textureId());
500 childContext3D->bindTexture(GL_TEXTURE_2D, lock.textureId());
501 childContext3D->getPixels(size, format, result);
502 EXPECT_EQ(0, memcmp(data1, result, pixelSize));
505 ResourceProvider::ScopedReadLockGL lock(childResourceProvider.get(), id2);
506 ASSERT_NE(0U, lock.textureId());
507 childContext3D->bindTexture(GL_TEXTURE_2D, lock.textureId());
508 childContext3D->getPixels(size, format, result);
509 EXPECT_EQ(0, memcmp(data2, result, pixelSize));
513 // Transfer resources to the parent again.
514 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
515 resourceIdsToTransfer.push_back(id1);
516 resourceIdsToTransfer.push_back(id2);
517 TransferableResourceList list;
518 childResourceProvider->prepareSendToParent(resourceIdsToTransfer, &list);
519 EXPECT_NE(0u, list.sync_point);
520 EXPECT_EQ(2u, list.resources.size());
521 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id1));
522 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id2));
523 m_resourceProvider->receiveFromChild(childId, list);
526 EXPECT_EQ(2u, m_resourceProvider->numResources());
527 m_resourceProvider->destroyChild(childId);
528 EXPECT_EQ(0u, m_resourceProvider->numResources());
531 TEST_P(ResourceProviderTest, DeleteTransferredResources)
533 // Resource transfer is only supported with GL textures for now.
534 if (GetParam() != ResourceProvider::GLTexture)
535 return;
537 scoped_ptr<GraphicsContext> childContext(FakeWebCompositorOutputSurface::create(ResourceProviderContext::create(m_sharedData.get()).PassAs<WebKit::WebGraphicsContext3D>()));
538 scoped_ptr<ResourceProvider> childResourceProvider(ResourceProvider::create(childContext.get()));
540 gfx::Size size(1, 1);
541 WGC3Denum format = GL_RGBA;
542 int pool = 1;
543 size_t pixelSize = textureSize(size, format);
544 ASSERT_EQ(4U, pixelSize);
546 ResourceProvider::ResourceId id = childResourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
547 uint8_t data[4] = {1, 2, 3, 4};
548 gfx::Rect rect(gfx::Point(), size);
549 childResourceProvider->setPixels(id, data, rect, rect, gfx::Vector2d());
551 int childPool = 2;
552 int childId = m_resourceProvider->createChild(childPool);
555 // Transfer some resource to the parent.
556 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
557 resourceIdsToTransfer.push_back(id);
558 TransferableResourceList list;
559 childResourceProvider->prepareSendToParent(resourceIdsToTransfer, &list);
560 EXPECT_NE(0u, list.sync_point);
561 EXPECT_EQ(1u, list.resources.size());
562 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id));
563 m_resourceProvider->receiveFromChild(childId, list);
566 // Delete textures in the child, while they are transfered.
567 childResourceProvider->deleteResource(id);
568 EXPECT_EQ(1u, childResourceProvider->numResources());
571 // Transfer resources back from the parent to the child.
572 ResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->getChildToParentMap(childId);
573 ResourceProvider::ResourceId mappedId = resourceMap[id];
574 EXPECT_NE(0u, mappedId);
575 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
576 resourceIdsToTransfer.push_back(mappedId);
577 TransferableResourceList list;
578 m_resourceProvider->prepareSendToChild(childId, resourceIdsToTransfer, &list);
579 EXPECT_NE(0u, list.sync_point);
580 EXPECT_EQ(1u, list.resources.size());
581 childResourceProvider->receiveFromParent(list);
583 EXPECT_EQ(0u, childResourceProvider->numResources());
586 class TextureStateTrackingContext : public FakeWebGraphicsContext3D {
587 public:
588 MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
589 MOCK_METHOD3(texParameteri, void(WGC3Denum target, WGC3Denum pname, WGC3Dint param));
592 TEST_P(ResourceProviderTest, ScopedSampler)
594 // Sampling is only supported for GL textures.
595 if (GetParam() != ResourceProvider::GLTexture)
596 return;
598 scoped_ptr<GraphicsContext> outputSurface(FakeWebCompositorOutputSurface::create(scoped_ptr<WebKit::WebGraphicsContext3D>(new TextureStateTrackingContext)));
599 TextureStateTrackingContext* context = static_cast<TextureStateTrackingContext*>(outputSurface->context3D());
600 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::create(outputSurface.get()));
602 gfx::Size size(1, 1);
603 WGC3Denum format = GL_RGBA;
604 int pool = 1;
605 int textureId = 1;
607 // Check that the texture gets created with the right sampler settings.
608 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
609 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
610 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
611 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
612 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
613 ResourceProvider::ResourceId id = resourceProvider->createResource(pool, size, format, ResourceProvider::TextureUsageAny);
615 // Creating a sampler with the default filter should not change any texture
616 // parameters.
618 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
619 ResourceProvider::ScopedSamplerGL sampler(resourceProvider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
622 // Using a different filter should be reflected in the texture parameters.
624 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
625 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST));
626 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
627 ResourceProvider::ScopedSamplerGL sampler(resourceProvider.get(), id, GL_TEXTURE_2D, GL_NEAREST);
630 // Test resetting to the default filter.
632 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
633 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
634 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
635 ResourceProvider::ScopedSamplerGL sampler(resourceProvider.get(), id, GL_TEXTURE_2D, GL_LINEAR);
638 Mock::VerifyAndClearExpectations(context);
641 INSTANTIATE_TEST_CASE_P(ResourceProviderTests,
642 ResourceProviderTest,
643 ::testing::Values(ResourceProvider::GLTexture,
644 ResourceProvider::Bitmap));
646 } // namespace
647 } // namespace cc