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

Side by Side Diff: cc/resource_provider_unittest.cc

Issue 12471007: Part 8 of cc/ directory shuffles: resources (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « cc/resource_provider.cc ('k') | cc/resource_update.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 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.
4
5 #include "cc/resource_provider.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "cc/base/scoped_ptr_deque.h"
10 #include "cc/base/scoped_ptr_hash_map.h"
11 #include "cc/output/output_surface.h"
12 #include "cc/test/fake_output_surface.h"
13 #include "cc/test/test_web_graphics_context_3d.h"
14 #include "gpu/GLES2/gl2extchromium.h"
15 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h"
18 #include "third_party/khronos/GLES2/gl2.h"
19 #include "third_party/khronos/GLES2/gl2ext.h"
20 #include "ui/gfx/rect.h"
21
22 using namespace WebKit;
23
24 using testing::Mock;
25 using testing::NiceMock;
26 using testing::Return;
27 using testing::StrictMock;
28 using testing::_;
29
30 namespace cc {
31 namespace {
32
33 size_t textureSize(const gfx::Size& size, WGC3Denum format)
34 {
35 unsigned int componentsPerPixel = 4;
36 unsigned int bytesPerComponent = 1;
37 return size.width() * size.height() * componentsPerPixel * bytesPerComponent ;
38 }
39
40 struct Texture {
41 Texture()
42 : format(0)
43 , filter(GL_NEAREST_MIPMAP_LINEAR)
44 {
45 }
46
47 void reallocate(const gfx::Size& size, WGC3Denum format)
48 {
49 this->size = size;
50 this->format = format;
51 this->data.reset(new uint8_t[textureSize(size, format)]);
52 }
53
54 gfx::Size size;
55 WGC3Denum format;
56 WGC3Denum filter;
57 scoped_array<uint8_t> data;
58 };
59
60 // Shared data between multiple ResourceProviderContext. This contains mailbox
61 // contents as well as information about sync points.
62 class ContextSharedData {
63 public:
64 static scoped_ptr<ContextSharedData> Create() { return make_scoped_ptr(new C ontextSharedData()); }
65
66 unsigned insertSyncPoint() { return m_nextSyncPoint++; }
67
68 void genMailbox(WGC3Dbyte* mailbox)
69 {
70 memset(mailbox, 0, sizeof(WGC3Dbyte[64]));
71 memcpy(mailbox, &m_nextMailBox, sizeof(m_nextMailBox));
72 ++m_nextMailBox;
73 }
74
75 void produceTexture(const WGC3Dbyte* mailboxName, unsigned syncPoint, scoped _ptr<Texture> texture)
76 {
77 unsigned mailbox = 0;
78 memcpy(&mailbox, mailboxName, sizeof(mailbox));
79 ASSERT_TRUE(mailbox && mailbox < m_nextMailBox);
80 m_textures.set(mailbox, texture.Pass());
81 ASSERT_LT(m_syncPointForMailbox[mailbox], syncPoint);
82 m_syncPointForMailbox[mailbox] = syncPoint;
83 }
84
85 scoped_ptr<Texture> consumeTexture(const WGC3Dbyte* mailboxName, unsigned sy ncPoint)
86 {
87 unsigned mailbox = 0;
88 memcpy(&mailbox, mailboxName, sizeof(mailbox));
89 DCHECK(mailbox && mailbox < m_nextMailBox);
90
91 // If the latest sync point the context has waited on is before the sync
92 // point for when the mailbox was set, pretend we never saw that
93 // produceTexture.
94 if (m_syncPointForMailbox[mailbox] > syncPoint) {
95 NOTREACHED();
96 return scoped_ptr<Texture>();
97 }
98 return m_textures.take(mailbox);
99 }
100
101 private:
102 ContextSharedData()
103 : m_nextSyncPoint(1)
104 , m_nextMailBox(1)
105 { }
106
107 unsigned m_nextSyncPoint;
108 unsigned m_nextMailBox;
109 typedef ScopedPtrHashMap<unsigned, Texture> TextureMap;
110 TextureMap m_textures;
111 base::hash_map<unsigned, unsigned> m_syncPointForMailbox;
112 };
113
114 class ResourceProviderContext : public TestWebGraphicsContext3D {
115 public:
116 static scoped_ptr<ResourceProviderContext> Create(ContextSharedData* sharedD ata) { return make_scoped_ptr(new ResourceProviderContext(Attributes(), sharedDa ta)); }
117
118 virtual unsigned insertSyncPoint()
119 {
120 unsigned syncPoint = m_sharedData->insertSyncPoint();
121 // Commit the produceTextureCHROMIUM calls at this point, so that
122 // they're associated with the sync point.
123 for (PendingProduceTextureList::iterator it = m_pendingProduceTextures.b egin(); it != m_pendingProduceTextures.end(); ++it)
124 m_sharedData->produceTexture((*it)->mailbox, syncPoint, (*it)->textu re.Pass());
125 m_pendingProduceTextures.clear();
126 return syncPoint;
127 }
128
129 virtual void waitSyncPoint(unsigned syncPoint)
130 {
131 m_lastWaitedSyncPoint = std::max(syncPoint, m_lastWaitedSyncPoint);
132 }
133
134 virtual void bindTexture(WGC3Denum target, WebGLId texture)
135 {
136 ASSERT_EQ(target, GL_TEXTURE_2D);
137 ASSERT_TRUE(!texture || m_textures.find(texture) != m_textures.end());
138 m_currentTexture = texture;
139 }
140
141 virtual WebGLId createTexture()
142 {
143 WebGLId id = TestWebGraphicsContext3D::createTexture();
144 m_textures.add(id, make_scoped_ptr(new Texture));
145 return id;
146 }
147
148 virtual void deleteTexture(WebGLId id)
149 {
150 TextureMap::iterator it = m_textures.find(id);
151 ASSERT_FALSE(it == m_textures.end());
152 m_textures.erase(it);
153 if (m_currentTexture == id)
154 m_currentTexture = 0;
155 }
156
157 virtual void texStorage2DEXT(WGC3Denum target, WGC3Dint levels, WGC3Duint in ternalformat,
158 WGC3Dint width, WGC3Dint height)
159 {
160 ASSERT_TRUE(m_currentTexture);
161 ASSERT_EQ(target, GL_TEXTURE_2D);
162 ASSERT_EQ(levels, 1);
163 WGC3Denum format = GL_RGBA;
164 switch (internalformat) {
165 case GL_RGBA8_OES:
166 break;
167 case GL_BGRA8_EXT:
168 format = GL_BGRA_EXT;
169 break;
170 default:
171 NOTREACHED();
172 }
173 allocateTexture(gfx::Size(width, height), format);
174 }
175
176 virtual void texImage2D(WGC3Denum target, WGC3Dint level, WGC3Denum internal format, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format, WGC3Denum type, const void* pixels)
177 {
178 ASSERT_TRUE(m_currentTexture);
179 ASSERT_EQ(target, GL_TEXTURE_2D);
180 ASSERT_FALSE(level);
181 ASSERT_EQ(internalformat, format);
182 ASSERT_FALSE(border);
183 ASSERT_EQ(type, GL_UNSIGNED_BYTE);
184 allocateTexture(gfx::Size(width, height), format);
185 if (pixels)
186 setPixels(0, 0, width, height, pixels);
187 }
188
189 virtual void texSubImage2D(WGC3Denum target, WGC3Dint level, WGC3Dint xoffse t, WGC3Dint yoffset, WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3 Denum type, const void* pixels)
190 {
191 ASSERT_TRUE(m_currentTexture);
192 ASSERT_EQ(target, GL_TEXTURE_2D);
193 ASSERT_FALSE(level);
194 ASSERT_TRUE(m_textures.get(m_currentTexture));
195 ASSERT_EQ(m_textures.get(m_currentTexture)->format, format);
196 ASSERT_EQ(type, GL_UNSIGNED_BYTE);
197 ASSERT_TRUE(pixels);
198 setPixels(xoffset, yoffset, width, height, pixels);
199 }
200
201 virtual void texParameteri(WGC3Denum target, WGC3Denum param, WGC3Dint value )
202 {
203 ASSERT_TRUE(m_currentTexture);
204 ASSERT_EQ(target, GL_TEXTURE_2D);
205 Texture* texture = m_textures.get(m_currentTexture);
206 ASSERT_TRUE(texture);
207 if (param != GL_TEXTURE_MIN_FILTER)
208 return;
209 texture->filter = value;
210 }
211
212 virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox) { return m_sharedData->g enMailbox(mailbox); }
213 virtual void produceTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailb ox)
214 {
215 ASSERT_TRUE(m_currentTexture);
216 ASSERT_EQ(target, GL_TEXTURE_2D);
217
218 // Delay moving the texture into the mailbox until the next
219 // insertSyncPoint, so that it is not visible to other contexts that
220 // haven't waited on that sync point.
221 scoped_ptr<PendingProduceTexture> pending(new PendingProduceTexture);
222 memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox));
223 pending->texture = m_textures.take(m_currentTexture);
224 m_textures.set(m_currentTexture, scoped_ptr<Texture>());
225 m_pendingProduceTextures.push_back(pending.Pass());
226 }
227
228 virtual void consumeTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailb ox)
229 {
230 ASSERT_TRUE(m_currentTexture);
231 ASSERT_EQ(target, GL_TEXTURE_2D);
232 m_textures.set(m_currentTexture, m_sharedData->consumeTexture(mailbox, m _lastWaitedSyncPoint));
233 }
234
235 void getPixels(const gfx::Size& size, WGC3Denum format, uint8_t* pixels)
236 {
237 ASSERT_TRUE(m_currentTexture);
238 Texture* texture = m_textures.get(m_currentTexture);
239 ASSERT_TRUE(texture);
240 ASSERT_EQ(texture->size, size);
241 ASSERT_EQ(texture->format, format);
242 memcpy(pixels, texture->data.get(), textureSize(size, format));
243 }
244
245 WGC3Denum getTextureFilter()
246 {
247 DCHECK(m_currentTexture);
248 Texture* texture = m_textures.get(m_currentTexture);
249 DCHECK(texture);
250 return texture->filter;
251 }
252
253 int textureCount()
254 {
255 return m_textures.size();
256 }
257
258 protected:
259 ResourceProviderContext(const Attributes& attrs, ContextSharedData* sharedDa ta)
260 : TestWebGraphicsContext3D(attrs)
261 , m_sharedData(sharedData)
262 , m_currentTexture(0)
263 , m_lastWaitedSyncPoint(0)
264 { }
265
266 private:
267 void allocateTexture(const gfx::Size& size, WGC3Denum format)
268 {
269 ASSERT_TRUE(m_currentTexture);
270 Texture* texture = m_textures.get(m_currentTexture);
271 ASSERT_TRUE(texture);
272 texture->reallocate(size, format);
273 }
274
275 void setPixels(int xoffset, int yoffset, int width, int height, const void* pixels)
276 {
277 ASSERT_TRUE(m_currentTexture);
278 Texture* texture = m_textures.get(m_currentTexture);
279 ASSERT_TRUE(texture);
280 ASSERT_TRUE(texture->data.get());
281 ASSERT_TRUE(xoffset >= 0 && xoffset+width <= texture->size.width());
282 ASSERT_TRUE(yoffset >= 0 && yoffset+height <= texture->size.height());
283 ASSERT_TRUE(pixels);
284 size_t inPitch = textureSize(gfx::Size(width, 1), texture->format);
285 size_t outPitch = textureSize(gfx::Size(texture->size.width(), 1), textu re->format);
286 uint8_t* dest = texture->data.get() + yoffset * outPitch + textureSize(g fx::Size(xoffset, 1), texture->format);
287 const uint8_t* src = static_cast<const uint8_t*>(pixels);
288 for (int i = 0; i < height; ++i) {
289 memcpy(dest, src, inPitch);
290 dest += outPitch;
291 src += inPitch;
292 }
293 }
294
295 typedef ScopedPtrHashMap<WebGLId, Texture> TextureMap;
296 struct PendingProduceTexture {
297 WGC3Dbyte mailbox[64];
298 scoped_ptr<Texture> texture;
299 };
300 typedef ScopedPtrDeque<PendingProduceTexture> PendingProduceTextureList;
301 ContextSharedData* m_sharedData;
302 WebGLId m_currentTexture;
303 TextureMap m_textures;
304 unsigned m_lastWaitedSyncPoint;
305 PendingProduceTextureList m_pendingProduceTextures;
306 };
307
308 class ResourceProviderTest : public testing::TestWithParam<ResourceProvider::Res ourceType> {
309 public:
310 ResourceProviderTest()
311 : m_sharedData(ContextSharedData::Create())
312 , m_outputSurface(FakeOutputSurface::Create3d(ResourceProviderContext::C reate(m_sharedData.get()).PassAs<WebKit::WebGraphicsContext3D>().PassAs<WebKit:: WebGraphicsContext3D>()))
313 , m_resourceProvider(ResourceProvider::Create(m_outputSurface.get()))
314 {
315 m_resourceProvider->set_default_resource_type(GetParam());
316 }
317
318 ResourceProviderContext* context() { return static_cast<ResourceProviderCont ext*>(m_outputSurface->context3d()); }
319
320 void getResourcePixels(ResourceProvider::ResourceId id, const gfx::Size& siz e, WGC3Denum format, uint8_t* pixels)
321 {
322 if (GetParam() == ResourceProvider::GLTexture) {
323 ResourceProvider::ScopedReadLockGL lockGL(m_resourceProvider.get(), id);
324 ASSERT_NE(0U, lockGL.texture_id());
325 context()->bindTexture(GL_TEXTURE_2D, lockGL.texture_id());
326 context()->getPixels(size, format, pixels);
327 } else if (GetParam() == ResourceProvider::Bitmap) {
328 ResourceProvider::ScopedReadLockSoftware lockSoftware(m_resourceProv ider.get(), id);
329 memcpy(pixels, lockSoftware.sk_bitmap()->getPixels(), lockSoftware.s k_bitmap()->getSize());
330 }
331 }
332
333 void setResourceFilter(ResourceProvider* resourceProvider, ResourceProvider: :ResourceId id, WGC3Denum filter)
334 {
335 ResourceProvider::ScopedSamplerGL sampler(resourceProvider, id, GL_TEXTU RE_2D, filter);
336 }
337
338 WGC3Denum getResourceFilter(ResourceProvider* resourceProvider, ResourceProv ider::ResourceId id)
339 {
340 DCHECK_EQ(GetParam(), ResourceProvider::GLTexture);
341 ResourceProvider::ScopedReadLockGL lockGL(resourceProvider, id);
342 EXPECT_NE(0u, lockGL.texture_id());
343 ResourceProviderContext* context = static_cast<ResourceProviderContext*> (resourceProvider->GraphicsContext3D());
344 context->bindTexture(GL_TEXTURE_2D, lockGL.texture_id());
345 return context->getTextureFilter();
346 }
347
348 void expectNumResources(int count)
349 {
350 EXPECT_EQ(count, static_cast<int>(m_resourceProvider->num_resources()));
351 if (GetParam() == ResourceProvider::GLTexture)
352 EXPECT_EQ(count, context()->textureCount());
353 }
354
355 protected:
356 scoped_ptr<ContextSharedData> m_sharedData;
357 scoped_ptr<OutputSurface> m_outputSurface;
358 scoped_ptr<ResourceProvider> m_resourceProvider;
359 };
360
361 TEST_P(ResourceProviderTest, Basic)
362 {
363 gfx::Size size(1, 1);
364 WGC3Denum format = GL_RGBA;
365 size_t pixelSize = textureSize(size, format);
366 ASSERT_EQ(4U, pixelSize);
367
368 ResourceProvider::ResourceId id = m_resourceProvider->CreateResource(size, f ormat, ResourceProvider::TextureUsageAny);
369 expectNumResources(1);
370
371 uint8_t data[4] = {1, 2, 3, 4};
372 gfx::Rect rect(gfx::Point(), size);
373 m_resourceProvider->SetPixels(id, data, rect, rect, gfx::Vector2d());
374
375 uint8_t result[4] = {0};
376 getResourcePixels(id, size, format, result);
377 EXPECT_EQ(0, memcmp(data, result, pixelSize));
378
379 m_resourceProvider->DeleteResource(id);
380 expectNumResources(0);
381 }
382
383 TEST_P(ResourceProviderTest, Upload)
384 {
385 gfx::Size size(2, 2);
386 WGC3Denum format = GL_RGBA;
387 size_t pixelSize = textureSize(size, format);
388 ASSERT_EQ(16U, pixelSize);
389
390 ResourceProvider::ResourceId id = m_resourceProvider->CreateResource(size, f ormat, ResourceProvider::TextureUsageAny);
391
392 uint8_t image[16] = {0};
393 gfx::Rect imageRect(gfx::Point(), size);
394 m_resourceProvider->SetPixels(id, image, imageRect, imageRect, gfx::Vector2d ());
395
396 for (uint8_t i = 0 ; i < pixelSize; ++i)
397 image[i] = i;
398
399 uint8_t result[16] = {0};
400 {
401 gfx::Rect sourceRect(0, 0, 1, 1);
402 gfx::Vector2d destOffset(0, 0);
403 m_resourceProvider->SetPixels(id, image, imageRect, sourceRect, destOffs et);
404
405 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0,
406 0, 0, 0, 0, 0, 0, 0, 0};
407 getResourcePixels(id, size, format, result);
408 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
409 }
410 {
411 gfx::Rect sourceRect(0, 0, 1, 1);
412 gfx::Vector2d destOffset(1, 1);
413 m_resourceProvider->SetPixels(id, image, imageRect, sourceRect, destOffs et);
414
415 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0,
416 0, 0, 0, 0, 0, 1, 2, 3};
417 getResourcePixels(id, size, format, result);
418 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
419 }
420 {
421 gfx::Rect sourceRect(1, 0, 1, 1);
422 gfx::Vector2d destOffset(0, 1);
423 m_resourceProvider->SetPixels(id, image, imageRect, sourceRect, destOffs et);
424
425 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0,
426 4, 5, 6, 7, 0, 1, 2, 3};
427 getResourcePixels(id, size, format, result);
428 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
429 }
430 {
431 gfx::Rect offsetImageRect(gfx::Point(100, 100), size);
432 gfx::Rect sourceRect(100, 100, 1, 1);
433 gfx::Vector2d destOffset(1, 0);
434 m_resourceProvider->SetPixels(id, image, offsetImageRect, sourceRect, de stOffset);
435
436 uint8_t expected[16] = {0, 1, 2, 3, 0, 1, 2, 3,
437 4, 5, 6, 7, 0, 1, 2, 3};
438 getResourcePixels(id, size, format, result);
439 EXPECT_EQ(0, memcmp(expected, result, pixelSize));
440 }
441
442
443 m_resourceProvider->DeleteResource(id);
444 }
445
446 TEST_P(ResourceProviderTest, TransferResources)
447 {
448 // Resource transfer is only supported with GL textures for now.
449 if (GetParam() != ResourceProvider::GLTexture)
450 return;
451
452 scoped_ptr<OutputSurface> childOutputSurface(FakeOutputSurface::Create3d(Res ourceProviderContext::Create(m_sharedData.get()).PassAs<WebKit::WebGraphicsConte xt3D>()));
453 scoped_ptr<ResourceProvider> childResourceProvider(ResourceProvider::Create( childOutputSurface.get()));
454
455 gfx::Size size(1, 1);
456 WGC3Denum format = GL_RGBA;
457 size_t pixelSize = textureSize(size, format);
458 ASSERT_EQ(4U, pixelSize);
459
460 ResourceProvider::ResourceId id1 = childResourceProvider->CreateResource(siz e, format, ResourceProvider::TextureUsageAny);
461 uint8_t data1[4] = {1, 2, 3, 4};
462 gfx::Rect rect(gfx::Point(), size);
463 childResourceProvider->SetPixels(id1, data1, rect, rect, gfx::Vector2d());
464
465 ResourceProvider::ResourceId id2 = childResourceProvider->CreateResource(siz e, format, ResourceProvider::TextureUsageAny);
466 uint8_t data2[4] = {5, 5, 5, 5};
467 childResourceProvider->SetPixels(id2, data2, rect, rect, gfx::Vector2d());
468
469 int childId = m_resourceProvider->CreateChild();
470
471 {
472 // Transfer some resources to the parent.
473 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
474 resourceIdsToTransfer.push_back(id1);
475 resourceIdsToTransfer.push_back(id2);
476 TransferableResourceArray list;
477 childResourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list) ;
478 ASSERT_EQ(2u, list.size());
479 EXPECT_NE(0u, list[0].sync_point);
480 EXPECT_NE(0u, list[1].sync_point);
481 EXPECT_TRUE(childResourceProvider->InUseByConsumer(id1));
482 EXPECT_TRUE(childResourceProvider->InUseByConsumer(id2));
483 m_resourceProvider->ReceiveFromChild(childId, list);
484 }
485
486 EXPECT_EQ(2u, m_resourceProvider->num_resources());
487 ResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->GetChildTo ParentMap(childId);
488 ResourceProvider::ResourceId mappedId1 = resourceMap[id1];
489 ResourceProvider::ResourceId mappedId2 = resourceMap[id2];
490 EXPECT_NE(0u, mappedId1);
491 EXPECT_NE(0u, mappedId2);
492 EXPECT_FALSE(m_resourceProvider->InUseByConsumer(id1));
493 EXPECT_FALSE(m_resourceProvider->InUseByConsumer(id2));
494
495 uint8_t result[4] = {0};
496 getResourcePixels(mappedId1, size, format, result);
497 EXPECT_EQ(0, memcmp(data1, result, pixelSize));
498
499 getResourcePixels(mappedId2, size, format, result);
500 EXPECT_EQ(0, memcmp(data2, result, pixelSize));
501
502 {
503 // Check that transfering again the same resource from the child to the
504 // parent is a noop.
505 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
506 resourceIdsToTransfer.push_back(id1);
507 TransferableResourceArray list;
508 childResourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list) ;
509 EXPECT_EQ(0u, list.size());
510 }
511
512 {
513 // Transfer resources back from the parent to the child.
514 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
515 resourceIdsToTransfer.push_back(mappedId1);
516 resourceIdsToTransfer.push_back(mappedId2);
517 TransferableResourceArray list;
518 m_resourceProvider->PrepareSendToChild(childId, resourceIdsToTransfer, & list);
519 ASSERT_EQ(2u, list.size());
520 EXPECT_NE(0u, list[0].sync_point);
521 EXPECT_NE(0u, list[1].sync_point);
522 childResourceProvider->ReceiveFromParent(list);
523 }
524 EXPECT_FALSE(childResourceProvider->InUseByConsumer(id1));
525 EXPECT_FALSE(childResourceProvider->InUseByConsumer(id2));
526
527 ResourceProviderContext* childContext3D = static_cast<ResourceProviderContex t*>(childOutputSurface->context3d());
528 {
529 ResourceProvider::ScopedReadLockGL lock(childResourceProvider.get(), id1 );
530 ASSERT_NE(0U, lock.texture_id());
531 childContext3D->bindTexture(GL_TEXTURE_2D, lock.texture_id());
532 childContext3D->getPixels(size, format, result);
533 EXPECT_EQ(0, memcmp(data1, result, pixelSize));
534 }
535 {
536 ResourceProvider::ScopedReadLockGL lock(childResourceProvider.get(), id2 );
537 ASSERT_NE(0U, lock.texture_id());
538 childContext3D->bindTexture(GL_TEXTURE_2D, lock.texture_id());
539 childContext3D->getPixels(size, format, result);
540 EXPECT_EQ(0, memcmp(data2, result, pixelSize));
541 }
542
543 {
544 // Transfer resources to the parent again.
545 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
546 resourceIdsToTransfer.push_back(id1);
547 resourceIdsToTransfer.push_back(id2);
548 TransferableResourceArray list;
549 childResourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list) ;
550 ASSERT_EQ(2u, list.size());
551 EXPECT_NE(0u, list[0].sync_point);
552 EXPECT_NE(0u, list[1].sync_point);
553 EXPECT_TRUE(childResourceProvider->InUseByConsumer(id1));
554 EXPECT_TRUE(childResourceProvider->InUseByConsumer(id2));
555 m_resourceProvider->ReceiveFromChild(childId, list);
556 }
557
558 EXPECT_EQ(2u, m_resourceProvider->num_resources());
559 m_resourceProvider->DestroyChild(childId);
560 EXPECT_EQ(0u, m_resourceProvider->num_resources());
561 }
562
563 TEST_P(ResourceProviderTest, DeleteTransferredResources)
564 {
565 // Resource transfer is only supported with GL textures for now.
566 if (GetParam() != ResourceProvider::GLTexture)
567 return;
568
569 scoped_ptr<OutputSurface> childOutputSurface(FakeOutputSurface::Create3d(Res ourceProviderContext::Create(m_sharedData.get()).PassAs<WebKit::WebGraphicsConte xt3D>()));
570 scoped_ptr<ResourceProvider> childResourceProvider(ResourceProvider::Create( childOutputSurface.get()));
571
572 gfx::Size size(1, 1);
573 WGC3Denum format = GL_RGBA;
574 size_t pixelSize = textureSize(size, format);
575 ASSERT_EQ(4U, pixelSize);
576
577 ResourceProvider::ResourceId id = childResourceProvider->CreateResource(size , format, ResourceProvider::TextureUsageAny);
578 uint8_t data[4] = {1, 2, 3, 4};
579 gfx::Rect rect(gfx::Point(), size);
580 childResourceProvider->SetPixels(id, data, rect, rect, gfx::Vector2d());
581
582 int childId = m_resourceProvider->CreateChild();
583
584 {
585 // Transfer some resource to the parent.
586 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
587 resourceIdsToTransfer.push_back(id);
588 TransferableResourceArray list;
589 childResourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list) ;
590 ASSERT_EQ(1u, list.size());
591 EXPECT_NE(0u, list[0].sync_point);
592 EXPECT_TRUE(childResourceProvider->InUseByConsumer(id));
593 m_resourceProvider->ReceiveFromChild(childId, list);
594 }
595
596 // Delete textures in the child, while they are transfered.
597 childResourceProvider->DeleteResource(id);
598 EXPECT_EQ(1u, childResourceProvider->num_resources());
599
600 {
601 // Transfer resources back from the parent to the child.
602 ResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->GetChi ldToParentMap(childId);
603 ResourceProvider::ResourceId mappedId = resourceMap[id];
604 EXPECT_NE(0u, mappedId);
605 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
606 resourceIdsToTransfer.push_back(mappedId);
607 TransferableResourceArray list;
608 m_resourceProvider->PrepareSendToChild(childId, resourceIdsToTransfer, & list);
609 ASSERT_EQ(1u, list.size());
610 EXPECT_NE(0u, list[0].sync_point);
611 childResourceProvider->ReceiveFromParent(list);
612 }
613 EXPECT_EQ(0u, childResourceProvider->num_resources());
614 }
615
616 TEST_P(ResourceProviderTest, TextureFilters)
617 {
618 // Resource transfer is only supported with GL textures for now.
619 if (GetParam() != ResourceProvider::GLTexture)
620 return;
621
622 scoped_ptr<OutputSurface> childOutputSurface(FakeOutputSurface::Create3d(Res ourceProviderContext::Create(m_sharedData.get()).PassAs<WebKit::WebGraphicsConte xt3D>()));
623 scoped_ptr<ResourceProvider> childResourceProvider(ResourceProvider::Create( childOutputSurface.get()));
624
625 gfx::Size size(1, 1);
626 WGC3Denum format = GL_RGBA;
627 size_t pixelSize = textureSize(size, format);
628 ASSERT_EQ(4U, pixelSize);
629
630 ResourceProvider::ResourceId id = childResourceProvider->CreateResource(size , format, ResourceProvider::TextureUsageAny);
631 uint8_t data[4] = {1, 2, 3, 4};
632 gfx::Rect rect(gfx::Point(), size);
633 childResourceProvider->SetPixels(id, data, rect, rect, gfx::Vector2d());
634 EXPECT_EQ(GL_LINEAR, getResourceFilter(childResourceProvider.get(), id));
635 setResourceFilter(childResourceProvider.get(), id, GL_NEAREST);
636 EXPECT_EQ(GL_NEAREST, getResourceFilter(childResourceProvider.get(), id));
637
638 int childId = m_resourceProvider->CreateChild();
639
640 {
641 // Transfer some resource to the parent.
642 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
643 resourceIdsToTransfer.push_back(id);
644 TransferableResourceArray list;
645 childResourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list) ;
646 ASSERT_EQ(1u, list.size());
647 EXPECT_EQ(GL_NEAREST, list[0].filter);
648 m_resourceProvider->ReceiveFromChild(childId, list);
649 }
650 ResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->GetChildTo ParentMap(childId);
651 ResourceProvider::ResourceId mappedId = resourceMap[id];
652 EXPECT_NE(0u, mappedId);
653 EXPECT_EQ(GL_NEAREST, getResourceFilter(m_resourceProvider.get(), mappedId)) ;
654 setResourceFilter(m_resourceProvider.get(), mappedId, GL_LINEAR);
655 EXPECT_EQ(GL_LINEAR, getResourceFilter(m_resourceProvider.get(), mappedId));
656 {
657 // Transfer resources back from the parent to the child.
658 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
659 resourceIdsToTransfer.push_back(mappedId);
660 TransferableResourceArray list;
661 m_resourceProvider->PrepareSendToChild(childId, resourceIdsToTransfer, & list);
662 ASSERT_EQ(1u, list.size());
663 EXPECT_EQ(GL_LINEAR, list[0].filter);
664 childResourceProvider->ReceiveFromParent(list);
665 }
666 EXPECT_EQ(GL_LINEAR, getResourceFilter(childResourceProvider.get(), id));
667 setResourceFilter(childResourceProvider.get(), id, GL_NEAREST);
668 EXPECT_EQ(GL_NEAREST, getResourceFilter(childResourceProvider.get(), id));
669 }
670
671 void ReleaseTextureMailbox(unsigned* releaseSyncPoint, unsigned syncPoint) {
672 *releaseSyncPoint = syncPoint;
673 }
674
675 TEST_P(ResourceProviderTest, TransferMailboxResources)
676 {
677 // Resource transfer is only supported with GL textures for now.
678 if (GetParam() != ResourceProvider::GLTexture)
679 return;
680 unsigned texture = context()->createTexture();
681 context()->bindTexture(GL_TEXTURE_2D, texture);
682 uint8_t data[4] = {1, 2, 3, 4};
683 context()->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGN ED_BYTE, &data);
684 gpu::Mailbox mailbox;
685 context()->genMailboxCHROMIUM(mailbox.name);
686 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
687 unsigned syncPoint = context()->insertSyncPoint();
688
689 // All the logic below assumes that the sync points are all positive.
690 EXPECT_LT(0u, syncPoint);
691
692 unsigned releaseSyncPoint = 0;
693 TextureMailbox::ReleaseCallback callback = base::Bind(ReleaseTextureMailbox, &releaseSyncPoint);
694 ResourceProvider::ResourceId resource = m_resourceProvider->CreateResourceFr omTextureMailbox(TextureMailbox(mailbox, callback, syncPoint));
695 EXPECT_EQ(1u, context()->textureCount());
696 EXPECT_EQ(0u, releaseSyncPoint);
697
698 {
699 // Transfer the resource, expect the sync points to be consistent.
700 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
701 resourceIdsToTransfer.push_back(resource);
702 TransferableResourceArray list;
703 m_resourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list);
704 ASSERT_EQ(1u, list.size());
705 EXPECT_LE(syncPoint, list[0].sync_point);
706 EXPECT_EQ(0u, memcmp(mailbox.name, list[0].mailbox.name, sizeof(mailbox. name)));
707 EXPECT_EQ(0u, releaseSyncPoint);
708
709 context()->waitSyncPoint(list[0].sync_point);
710 unsigned otherTexture = context()->createTexture();
711 context()->bindTexture(GL_TEXTURE_2D, otherTexture);
712 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
713 uint8_t testData[4] = {0};
714 context()->getPixels(gfx::Size(1, 1), GL_RGBA, testData);
715 EXPECT_EQ(0u, memcmp(data, testData, sizeof(data)));
716 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
717 context()->deleteTexture(otherTexture);
718 list[0].sync_point = context()->insertSyncPoint();
719 EXPECT_LT(0u, list[0].sync_point);
720
721 // Receive the resource, then delete it, expect the sync points to be co nsistent.
722 m_resourceProvider->ReceiveFromParent(list);
723 EXPECT_EQ(1u, context()->textureCount());
724 EXPECT_EQ(0u, releaseSyncPoint);
725
726 m_resourceProvider->DeleteResource(resource);
727 EXPECT_LE(list[0].sync_point, releaseSyncPoint);
728 }
729
730
731 // We're going to do the same thing as above, but testing the case where we
732 // delete the resource before we receive it back.
733 syncPoint = releaseSyncPoint;
734 EXPECT_LT(0u, syncPoint);
735 releaseSyncPoint = 0;
736 resource = m_resourceProvider->CreateResourceFromTextureMailbox(TextureMailb ox(mailbox, callback, syncPoint));
737 EXPECT_EQ(1u, context()->textureCount());
738 EXPECT_EQ(0u, releaseSyncPoint);
739
740 {
741 // Transfer the resource, expect the sync points to be consistent.
742 ResourceProvider::ResourceIdArray resourceIdsToTransfer;
743 resourceIdsToTransfer.push_back(resource);
744 TransferableResourceArray list;
745 m_resourceProvider->PrepareSendToParent(resourceIdsToTransfer, &list);
746 ASSERT_EQ(1u, list.size());
747 EXPECT_LE(syncPoint, list[0].sync_point);
748 EXPECT_EQ(0u, memcmp(mailbox.name, list[0].mailbox.name, sizeof(mailbox. name)));
749 EXPECT_EQ(0u, releaseSyncPoint);
750
751 context()->waitSyncPoint(list[0].sync_point);
752 unsigned otherTexture = context()->createTexture();
753 context()->bindTexture(GL_TEXTURE_2D, otherTexture);
754 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
755 uint8_t testData[4] = {0};
756 context()->getPixels(gfx::Size(1, 1), GL_RGBA, testData);
757 EXPECT_EQ(0u, memcmp(data, testData, sizeof(data)));
758 context()->produceTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
759 context()->deleteTexture(otherTexture);
760 list[0].sync_point = context()->insertSyncPoint();
761 EXPECT_LT(0u, list[0].sync_point);
762
763 // Delete the resource, which shouldn't do anything.
764 m_resourceProvider->DeleteResource(resource);
765 EXPECT_EQ(1u, context()->textureCount());
766 EXPECT_EQ(0u, releaseSyncPoint);
767
768 // Then receive the resource which should release the mailbox, expect th e sync points to be consistent.
769 m_resourceProvider->ReceiveFromParent(list);
770 EXPECT_LE(list[0].sync_point, releaseSyncPoint);
771 }
772
773 context()->waitSyncPoint(releaseSyncPoint);
774 context()->bindTexture(GL_TEXTURE_2D, texture);
775 context()->consumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name);
776 context()->deleteTexture(texture);
777 }
778
779 class TextureStateTrackingContext : public TestWebGraphicsContext3D {
780 public:
781 MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
782 MOCK_METHOD3(texParameteri, void(WGC3Denum target, WGC3Denum pname, WGC3Dint param));
783
784 // Force all textures to be "1" so we can test for them.
785 virtual WebKit::WebGLId NextTextureId() { return 1; }
786 };
787
788 TEST_P(ResourceProviderTest, ScopedSampler)
789 {
790 // Sampling is only supported for GL textures.
791 if (GetParam() != ResourceProvider::GLTexture)
792 return;
793
794 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new TextureStateTrackingContext)));
795 TextureStateTrackingContext* context = static_cast<TextureStateTrackingConte xt*>(outputSurface->context3d());
796 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get()));
797
798 gfx::Size size(1, 1);
799 WGC3Denum format = GL_RGBA;
800 int textureId = 1;
801
802 // Check that the texture gets created with the right sampler settings.
803 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId))
804 .Times(2); // Once to create and once to allocate.
805 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL _LINEAR));
806 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL _LINEAR));
807 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLA MP_TO_EDGE));
808 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLA MP_TO_EDGE));
809 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
810 ResourceProvider::ResourceId id = resourceProvider->CreateResource(size, for mat, ResourceProvider::TextureUsageAny);
811 resourceProvider->AllocateForTesting(id);
812
813 // Creating a sampler with the default filter should not change any texture
814 // parameters.
815 {
816 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
817 ResourceProvider::ScopedSamplerGL sampler(resourceProvider.get(), id, GL _TEXTURE_2D, GL_LINEAR);
818 }
819
820 // Using a different filter should be reflected in the texture parameters.
821 {
822 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
823 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_NEAREST));
824 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_NEAREST));
825 ResourceProvider::ScopedSamplerGL sampler(resourceProvider.get(), id, GL _TEXTURE_2D, GL_NEAREST);
826 }
827
828 // Test resetting to the default filter.
829 {
830 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
831 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER , GL_LINEAR));
832 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER , GL_LINEAR));
833 ResourceProvider::ScopedSamplerGL sampler(resourceProvider.get(), id, GL _TEXTURE_2D, GL_LINEAR);
834 }
835
836 Mock::VerifyAndClearExpectations(context);
837 }
838
839 TEST_P(ResourceProviderTest, ManagedResource)
840 {
841 // Sampling is only supported for GL textures.
842 if (GetParam() != ResourceProvider::GLTexture)
843 return;
844
845 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(scoped_p tr<WebKit::WebGraphicsContext3D>(new TextureStateTrackingContext)));
846 TextureStateTrackingContext* context = static_cast<TextureStateTrackingConte xt*>(outputSurface->context3d());
847 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get()));
848
849 gfx::Size size(1, 1);
850 WGC3Denum format = GL_RGBA;
851 int textureId = 1;
852
853 // Check that the texture gets created with the right sampler settings.
854 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId));
855 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL _LINEAR));
856 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL _LINEAR));
857 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLA MP_TO_EDGE));
858 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLA MP_TO_EDGE));
859 EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_TEXTURE_POOL_MANAGED_CHROMIUM));
860 ResourceProvider::ResourceId id = resourceProvider->CreateManagedResource(si ze, format, ResourceProvider::TextureUsageAny);
861
862 Mock::VerifyAndClearExpectations(context);
863 }
864
865 class AllocationTrackingContext3D : public TestWebGraphicsContext3D {
866 public:
867 MOCK_METHOD0(createTexture, WebGLId());
868 MOCK_METHOD1(deleteTexture, void(WebGLId texture_id));
869 MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
870 MOCK_METHOD9(texImage2D, void(WGC3Denum target, WGC3Dint level, WGC3Denum in ternalformat,
871 WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format,
872 WGC3Denum type, const void* pixels));
873 MOCK_METHOD9(texSubImage2D, void(WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
874 WGC3Dsizei width, WGC3Dsizei height, WGC3De num format,
875 WGC3Denum type, const void* pixels));
876 MOCK_METHOD9(asyncTexImage2DCHROMIUM, void(WGC3Denum target, WGC3Dint level, WGC3Denum internalformat,
877 WGC3Dsizei width, WGC3Dsizei heigh t, WGC3Dint border, WGC3Denum format,
878 WGC3Denum type, const void* pixels ));
879 MOCK_METHOD9(asyncTexSubImage2DCHROMIUM, void(WGC3Denum target, WGC3Dint lev el, WGC3Dint xoffset, WGC3Dint yoffset,
880 WGC3Dsizei width, WGC3Dsizei h eight, WGC3Denum format,
881 WGC3Denum type, const void* pi xels));
882 MOCK_METHOD1(waitAsyncTexImage2DCHROMIUM, void(WGC3Denum target));
883 };
884
885 TEST_P(ResourceProviderTest, TextureAllocation)
886 {
887 // Only for GL textures.
888 if (GetParam() != ResourceProvider::GLTexture)
889 return;
890 scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
891 static_cast<WebKit::WebGraphicsContext3D*>(new NiceMock<AllocationTracki ngContext3D>));
892 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(mock_con text.Pass()));
893
894 gfx::Size size(2, 2);
895 gfx::Vector2d offset(0, 0);
896 gfx::Rect rect(0, 0, 2, 2);
897 WGC3Denum format = GL_RGBA;
898 ResourceProvider::ResourceId id = 0;
899 uint8_t pixels[16] = {0};
900 int textureId = 123;
901
902 AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext 3D*>(outputSurface->context3d());
903 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get()));
904
905 // Lazy allocation. Don't allocate when creating the resource.
906 EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
907 EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
908 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(1);
909 EXPECT_CALL(*context, texImage2D(_,_,_,_,_,_,_,_,_)).Times(0);
910 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_,_,_,_,_,_,_,_,_)).Times(0);
911 id = resourceProvider->CreateResource(size, format, ResourceProvider::Textur eUsageAny);
912 resourceProvider->DeleteResource(id);
913 Mock::VerifyAndClearExpectations(context);
914
915 // Do allocate when we set the pixels.
916 EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
917 EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
918 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(3);
919 EXPECT_CALL(*context, texImage2D(_,_,_,2,2,_,_,_,_)).Times(1);
920 EXPECT_CALL(*context, texSubImage2D(_,_,_,_,2,2,_,_,_)).Times(1);
921 id = resourceProvider->CreateResource(size, format, ResourceProvider::Textur eUsageAny);
922 resourceProvider->SetPixels(id, pixels, rect, rect, offset);
923 resourceProvider->DeleteResource(id);
924 Mock::VerifyAndClearExpectations(context);
925
926 // Same for setPixelsFromBuffer
927 EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
928 EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
929 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(3);
930 EXPECT_CALL(*context, texImage2D(_,_,_,2,2,_,_,_,_)).Times(1);
931 EXPECT_CALL(*context, texSubImage2D(_,_,_,_,2,2,_,_,_)).Times(1);
932 id = resourceProvider->CreateResource(size, format, ResourceProvider::Textur eUsageAny);
933 resourceProvider->AcquirePixelBuffer(id);
934 resourceProvider->SetPixelsFromBuffer(id);
935 resourceProvider->ReleasePixelBuffer(id);
936 resourceProvider->DeleteResource(id);
937 Mock::VerifyAndClearExpectations(context);
938
939 // Same for async version.
940 EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
941 EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
942 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(2);
943 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_,_,_,2,2,_,_,_,_)).Times(1);
944 id = resourceProvider->CreateResource(size, format, ResourceProvider::Textur eUsageAny);
945 resourceProvider->AcquirePixelBuffer(id);
946 resourceProvider->BeginSetPixels(id);
947 resourceProvider->ReleasePixelBuffer(id);
948 resourceProvider->DeleteResource(id);
949 Mock::VerifyAndClearExpectations(context);
950 }
951
952 TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete)
953 {
954 // Only for GL textures.
955 if (GetParam() != ResourceProvider::GLTexture)
956 return;
957 scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
958 static_cast<WebKit::WebGraphicsContext3D*>(new NiceMock<AllocationTracki ngContext3D>));
959 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(mock_con text.Pass()));
960
961 gfx::Size size(2, 2);
962 WGC3Denum format = GL_RGBA;
963 ResourceProvider::ResourceId id = 0;
964 int textureId = 123;
965
966 AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext 3D*>(outputSurface->context3d());
967 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get()));
968
969 EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
970 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(3);
971 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_,_,_,2,2,_,_,_,_)).Times(1);
972 EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
973 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
974 id = resourceProvider->CreateResource(size, format, ResourceProvider::Textur eUsageAny);
975 resourceProvider->AcquirePixelBuffer(id);
976 resourceProvider->BeginSetPixels(id);
977 resourceProvider->ForceSetPixelsToComplete(id);
978 resourceProvider->ReleasePixelBuffer(id);
979 Mock::VerifyAndClearExpectations(context);
980 }
981
982 TEST_P(ResourceProviderTest, AbortForcedAsyncUpload)
983 {
984 // Only for GL textures.
985 if (GetParam() != ResourceProvider::GLTexture)
986 return;
987 scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
988 static_cast<WebKit::WebGraphicsContext3D*>(new NiceMock<AllocationTracki ngContext3D>));
989 scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(mock_con text.Pass()));
990
991 gfx::Size size(2, 2);
992 WGC3Denum format = GL_RGBA;
993 ResourceProvider::ResourceId id = 0;
994 int textureId = 123;
995
996 AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext 3D*>(outputSurface->context3d());
997 scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::Create(outpu tSurface.get()));
998
999 EXPECT_CALL(*context, createTexture()).WillRepeatedly(Return(textureId));
1000 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(4);
1001 EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_,_,_,2,2,_,_,_,_)).Times(1);
1002 EXPECT_CALL(*context, waitAsyncTexImage2DCHROMIUM(GL_TEXTURE_2D)).Times(1);
1003 EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, 0)).Times(1);
1004 EXPECT_CALL(*context, deleteTexture(_)).Times(1);
1005 id = resourceProvider->CreateResource(size, format, ResourceProvider::Textur eUsageAny);
1006 resourceProvider->AcquirePixelBuffer(id);
1007 resourceProvider->BeginSetPixels(id);
1008 resourceProvider->ForceSetPixelsToComplete(id);
1009 resourceProvider->AbortSetPixels(id);
1010 resourceProvider->ReleasePixelBuffer(id);
1011 Mock::VerifyAndClearExpectations(context);
1012 }
1013
1014 INSTANTIATE_TEST_CASE_P(ResourceProviderTests,
1015 ResourceProviderTest,
1016 ::testing::Values(ResourceProvider::GLTexture,
1017 ResourceProvider::Bitmap));
1018
1019 } // namespace
1020 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resource_provider.cc ('k') | cc/resource_update.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698