OLD | NEW |
| (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 "config.h" | |
6 | |
7 #include "CCResourceProvider.h" | |
8 | |
9 #include "CCGraphicsContext.h" | |
10 #include "CCSingleThreadProxy.h" // For DebugScopedSetImplThread | |
11 #include "CompositorFakeWebGraphicsContext3D.h" | |
12 #include "Extensions3DChromium.h" | |
13 #include "FakeWebCompositorOutputSurface.h" | |
14 #include "testing/gtest/include/gtest/gtest.h" | |
15 #include <public/WebGraphicsContext3D.h> | |
16 #include <wtf/HashMap.h> | |
17 #include <wtf/OwnArrayPtr.h> | |
18 #include <wtf/OwnPtr.h> | |
19 | |
20 using namespace cc; | |
21 using namespace WebKit; | |
22 | |
23 namespace { | |
24 | |
25 size_t textureSize(const IntSize& size, WGC3Denum format) | |
26 { | |
27 unsigned int componentsPerPixel = 4; | |
28 unsigned int bytesPerComponent = 1; | |
29 return size.width() * size.height() * componentsPerPixel * bytesPerComponent
; | |
30 } | |
31 | |
32 struct Texture { | |
33 Texture(const IntSize& size, WGC3Denum format) | |
34 : size(size) | |
35 , format(format) | |
36 , data(adoptArrayPtr(new uint8_t[textureSize(size, format)])) | |
37 { | |
38 } | |
39 | |
40 IntSize size; | |
41 WGC3Denum format; | |
42 OwnArrayPtr<uint8_t> data; | |
43 }; | |
44 | |
45 // Shared data between multiple ResourceProviderContext. This contains mailbox | |
46 // contents as well as information about sync points. | |
47 class ContextSharedData { | |
48 public: | |
49 static PassOwnPtr<ContextSharedData> create() { return adoptPtr(new ContextS
haredData()); } | |
50 | |
51 unsigned insertSyncPoint() { return m_nextSyncPoint++; } | |
52 | |
53 void genMailbox(WGC3Dbyte* mailbox) | |
54 { | |
55 memset(mailbox, 0, sizeof(WGC3Dbyte[64])); | |
56 memcpy(mailbox, &m_nextMailBox, sizeof(m_nextMailBox)); | |
57 ++m_nextMailBox; | |
58 } | |
59 | |
60 void produceTexture(const WGC3Dbyte* mailboxName, unsigned syncPoint, PassOw
nPtr<Texture> texture) | |
61 { | |
62 unsigned mailbox = 0; | |
63 memcpy(&mailbox, mailboxName, sizeof(mailbox)); | |
64 ASSERT(mailbox && mailbox < m_nextMailBox); | |
65 m_textures.set(mailbox, texture); | |
66 ASSERT(m_syncPointForMailbox.get(mailbox) < syncPoint); | |
67 m_syncPointForMailbox.set(mailbox, syncPoint); | |
68 } | |
69 | |
70 PassOwnPtr<Texture> consumeTexture(const WGC3Dbyte* mailboxName, unsigned sy
ncPoint) | |
71 { | |
72 unsigned mailbox = 0; | |
73 memcpy(&mailbox, mailboxName, sizeof(mailbox)); | |
74 ASSERT(mailbox && mailbox < m_nextMailBox); | |
75 | |
76 // If the latest sync point the context has waited on is before the sync | |
77 // point for when the mailbox was set, pretend we never saw that | |
78 // produceTexture. | |
79 if (m_syncPointForMailbox.get(mailbox) < syncPoint) | |
80 return nullptr; | |
81 return m_textures.take(mailbox); | |
82 } | |
83 | |
84 private: | |
85 ContextSharedData() | |
86 : m_nextSyncPoint(1) | |
87 , m_nextMailBox(1) | |
88 { } | |
89 | |
90 unsigned m_nextSyncPoint; | |
91 unsigned m_nextMailBox; | |
92 typedef HashMap<unsigned, OwnPtr<Texture> > TextureMap; | |
93 TextureMap m_textures; | |
94 HashMap<unsigned, unsigned> m_syncPointForMailbox; | |
95 }; | |
96 | |
97 class ResourceProviderContext : public CompositorFakeWebGraphicsContext3D { | |
98 public: | |
99 static PassOwnPtr<ResourceProviderContext> create(ContextSharedData* sharedD
ata) { return adoptPtr(new ResourceProviderContext(Attributes(), sharedData)); } | |
100 | |
101 virtual unsigned insertSyncPoint() | |
102 { | |
103 unsigned syncPoint = m_sharedData->insertSyncPoint(); | |
104 // Commit the produceTextureCHROMIUM calls at this point, so that | |
105 // they're associated with the sync point. | |
106 for (PendingProduceTextureList::iterator it = m_pendingProduceTextures.b
egin(); it != m_pendingProduceTextures.end(); ++it) | |
107 m_sharedData->produceTexture((*it)->mailbox, syncPoint, (*it)->textu
re.release()); | |
108 m_pendingProduceTextures.clear(); | |
109 return syncPoint; | |
110 } | |
111 | |
112 virtual void waitSyncPoint(unsigned syncPoint) | |
113 { | |
114 m_lastWaitedSyncPoint = std::max(syncPoint, m_lastWaitedSyncPoint); | |
115 } | |
116 | |
117 virtual void bindTexture(WGC3Denum target, WebGLId texture) | |
118 { | |
119 ASSERT(target == GraphicsContext3D::TEXTURE_2D); | |
120 ASSERT(!texture || m_textures.find(texture) != m_textures.end()); | |
121 m_currentTexture = texture; | |
122 } | |
123 | |
124 virtual WebGLId createTexture() | |
125 { | |
126 WebGLId id = CompositorFakeWebGraphicsContext3D::createTexture(); | |
127 m_textures.add(id, nullptr); | |
128 return id; | |
129 } | |
130 | |
131 virtual void deleteTexture(WebGLId id) | |
132 { | |
133 TextureMap::iterator it = m_textures.find(id); | |
134 ASSERT(it != m_textures.end()); | |
135 m_textures.remove(it); | |
136 if (m_currentTexture == id) | |
137 m_currentTexture = 0; | |
138 } | |
139 | |
140 virtual void texStorage2DEXT(WGC3Denum target, WGC3Dint levels, WGC3Duint in
ternalformat, | |
141 WGC3Dint width, WGC3Dint height) | |
142 { | |
143 ASSERT(m_currentTexture); | |
144 ASSERT(target == GraphicsContext3D::TEXTURE_2D); | |
145 ASSERT(levels == 1); | |
146 WGC3Denum format = GraphicsContext3D::RGBA; | |
147 switch (internalformat) { | |
148 case Extensions3D::RGBA8_OES: | |
149 break; | |
150 case Extensions3DChromium::BGRA8_EXT: | |
151 format = Extensions3D::BGRA_EXT; | |
152 break; | |
153 default: | |
154 ASSERT_NOT_REACHED(); | |
155 } | |
156 allocateTexture(IntSize(width, height), format); | |
157 } | |
158 | |
159 virtual void texImage2D(WGC3Denum target, WGC3Dint level, WGC3Denum internal
format, WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format,
WGC3Denum type, const void* pixels) | |
160 { | |
161 ASSERT(m_currentTexture); | |
162 ASSERT(target == GraphicsContext3D::TEXTURE_2D); | |
163 ASSERT(!level); | |
164 ASSERT(internalformat == format); | |
165 ASSERT(!border); | |
166 ASSERT(type == GraphicsContext3D::UNSIGNED_BYTE); | |
167 allocateTexture(IntSize(width, height), format); | |
168 if (pixels) | |
169 setPixels(0, 0, width, height, pixels); | |
170 } | |
171 | |
172 virtual void texSubImage2D(WGC3Denum target, WGC3Dint level, WGC3Dint xoffse
t, WGC3Dint yoffset, WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3
Denum type, const void* pixels) | |
173 { | |
174 ASSERT(m_currentTexture); | |
175 ASSERT(target == GraphicsContext3D::TEXTURE_2D); | |
176 ASSERT(!level); | |
177 ASSERT(m_textures.get(m_currentTexture)); | |
178 ASSERT(m_textures.get(m_currentTexture)->format == format); | |
179 ASSERT(type == GraphicsContext3D::UNSIGNED_BYTE); | |
180 ASSERT(pixels); | |
181 setPixels(xoffset, yoffset, width, height, pixels); | |
182 } | |
183 | |
184 virtual void genMailboxCHROMIUM(WGC3Dbyte* mailbox) { return m_sharedData->g
enMailbox(mailbox); } | |
185 virtual void produceTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailb
ox) | |
186 { | |
187 ASSERT(m_currentTexture); | |
188 ASSERT(target == GraphicsContext3D::TEXTURE_2D); | |
189 | |
190 // Delay movind the texture into the mailbox until the next | |
191 // insertSyncPoint, so that it is not visible to other contexts that | |
192 // haven't waited on that sync point. | |
193 OwnPtr<PendingProduceTexture> pending(adoptPtr(new PendingProduceTexture
)); | |
194 memcpy(pending->mailbox, mailbox, sizeof(pending->mailbox)); | |
195 pending->texture = m_textures.take(m_currentTexture); | |
196 m_textures.set(m_currentTexture, nullptr); | |
197 m_pendingProduceTextures.append(pending.release()); | |
198 } | |
199 | |
200 virtual void consumeTextureCHROMIUM(WGC3Denum target, const WGC3Dbyte* mailb
ox) | |
201 { | |
202 ASSERT(m_currentTexture); | |
203 ASSERT(target == GraphicsContext3D::TEXTURE_2D); | |
204 m_textures.set(m_currentTexture, m_sharedData->consumeTexture(mailbox, m
_lastWaitedSyncPoint)); | |
205 } | |
206 | |
207 void getPixels(const IntSize& size, WGC3Denum format, uint8_t* pixels) | |
208 { | |
209 ASSERT(m_currentTexture); | |
210 Texture* texture = m_textures.get(m_currentTexture); | |
211 ASSERT(texture); | |
212 ASSERT(texture->size == size); | |
213 ASSERT(texture->format == format); | |
214 memcpy(pixels, texture->data.get(), textureSize(size, format)); | |
215 } | |
216 | |
217 int textureCount() | |
218 { | |
219 return m_textures.size(); | |
220 } | |
221 | |
222 protected: | |
223 ResourceProviderContext(const Attributes& attrs, ContextSharedData* sharedDa
ta) | |
224 : CompositorFakeWebGraphicsContext3D(attrs) | |
225 , m_sharedData(sharedData) | |
226 , m_currentTexture(0) | |
227 , m_lastWaitedSyncPoint(0) | |
228 { } | |
229 | |
230 private: | |
231 void allocateTexture(const IntSize& size, WGC3Denum format) | |
232 { | |
233 ASSERT(m_currentTexture); | |
234 m_textures.set(m_currentTexture, adoptPtr(new Texture(size, format))); | |
235 } | |
236 | |
237 void setPixels(int xoffset, int yoffset, int width, int height, const void*
pixels) | |
238 { | |
239 ASSERT(m_currentTexture); | |
240 Texture* texture = m_textures.get(m_currentTexture); | |
241 ASSERT(texture); | |
242 ASSERT(xoffset >= 0 && xoffset+width <= texture->size.width()); | |
243 ASSERT(yoffset >= 0 && yoffset+height <= texture->size.height()); | |
244 ASSERT(pixels); | |
245 size_t inPitch = textureSize(IntSize(width, 1), texture->format); | |
246 size_t outPitch = textureSize(IntSize(texture->size.width(), 1), texture
->format); | |
247 uint8_t* dest = texture->data.get() + yoffset * outPitch + textureSize(I
ntSize(xoffset, 1), texture->format); | |
248 const uint8_t* src = static_cast<const uint8_t*>(pixels); | |
249 for (int i = 0; i < height; ++i) { | |
250 memcpy(dest, src, inPitch); | |
251 dest += outPitch; | |
252 src += inPitch; | |
253 } | |
254 } | |
255 | |
256 typedef HashMap<WebGLId, OwnPtr<Texture> > TextureMap; | |
257 struct PendingProduceTexture { | |
258 WGC3Dbyte mailbox[64]; | |
259 OwnPtr<Texture> texture; | |
260 }; | |
261 typedef Deque<OwnPtr<PendingProduceTexture> > PendingProduceTextureList; | |
262 ContextSharedData* m_sharedData; | |
263 WebGLId m_currentTexture; | |
264 TextureMap m_textures; | |
265 unsigned m_lastWaitedSyncPoint; | |
266 PendingProduceTextureList m_pendingProduceTextures; | |
267 }; | |
268 | |
269 class CCResourceProviderTest : public testing::TestWithParam<CCResourceProvider:
:ResourceType> { | |
270 public: | |
271 CCResourceProviderTest() | |
272 : m_sharedData(ContextSharedData::create()) | |
273 , m_context(FakeWebCompositorOutputSurface::create(ResourceProviderConte
xt::create(m_sharedData.get()))) | |
274 , m_resourceProvider(CCResourceProvider::create(m_context.get())) | |
275 { | |
276 m_resourceProvider->setDefaultResourceType(GetParam()); | |
277 } | |
278 | |
279 ResourceProviderContext* context() { return static_cast<ResourceProviderCont
ext*>(m_context->context3D()); } | |
280 | |
281 void getResourcePixels(CCResourceProvider::ResourceId id, const IntSize& siz
e, WGC3Denum format, uint8_t* pixels) | |
282 { | |
283 if (GetParam() == CCResourceProvider::GLTexture) { | |
284 CCResourceProvider::ScopedReadLockGL lockGL(m_resourceProvider.get()
, id); | |
285 ASSERT_NE(0U, lockGL.textureId()); | |
286 context()->bindTexture(GraphicsContext3D::TEXTURE_2D, lockGL.texture
Id()); | |
287 context()->getPixels(size, format, pixels); | |
288 } else if (GetParam() == CCResourceProvider::Bitmap) { | |
289 CCResourceProvider::ScopedReadLockSoftware lockSoftware(m_resourcePr
ovider.get(), id); | |
290 memcpy(pixels, lockSoftware.skBitmap()->getPixels(), lockSoftware.sk
Bitmap()->getSize()); | |
291 } | |
292 } | |
293 | |
294 void expectNumResources(int count) | |
295 { | |
296 EXPECT_EQ(count, static_cast<int>(m_resourceProvider->numResources())); | |
297 if (GetParam() == CCResourceProvider::GLTexture) | |
298 EXPECT_EQ(count, context()->textureCount()); | |
299 } | |
300 | |
301 protected: | |
302 DebugScopedSetImplThread implThread; | |
303 OwnPtr<ContextSharedData> m_sharedData; | |
304 scoped_ptr<CCGraphicsContext> m_context; | |
305 OwnPtr<CCResourceProvider> m_resourceProvider; | |
306 }; | |
307 | |
308 TEST_P(CCResourceProviderTest, Basic) | |
309 { | |
310 IntSize size(1, 1); | |
311 WGC3Denum format = GraphicsContext3D::RGBA; | |
312 int pool = 1; | |
313 size_t pixelSize = textureSize(size, format); | |
314 ASSERT_EQ(4U, pixelSize); | |
315 | |
316 CCResourceProvider::ResourceId id = m_resourceProvider->createResource(pool,
size, format, CCResourceProvider::TextureUsageAny); | |
317 expectNumResources(1); | |
318 | |
319 uint8_t data[4] = {1, 2, 3, 4}; | |
320 IntRect rect(IntPoint(), size); | |
321 m_resourceProvider->upload(id, data, rect, rect, IntSize()); | |
322 | |
323 uint8_t result[4] = {0}; | |
324 getResourcePixels(id, size, format, result); | |
325 EXPECT_EQ(0, memcmp(data, result, pixelSize)); | |
326 | |
327 m_resourceProvider->deleteResource(id); | |
328 expectNumResources(0); | |
329 } | |
330 | |
331 TEST_P(CCResourceProviderTest, DeleteOwnedResources) | |
332 { | |
333 IntSize size(1, 1); | |
334 WGC3Denum format = GraphicsContext3D::RGBA; | |
335 int pool = 1; | |
336 | |
337 const int count = 3; | |
338 for (int i = 0; i < count; ++i) | |
339 m_resourceProvider->createResource(pool, size, format, CCResourceProvide
r::TextureUsageAny); | |
340 expectNumResources(3); | |
341 | |
342 m_resourceProvider->deleteOwnedResources(pool+1); | |
343 expectNumResources(3); | |
344 | |
345 m_resourceProvider->deleteOwnedResources(pool); | |
346 expectNumResources(0); | |
347 } | |
348 | |
349 TEST_P(CCResourceProviderTest, Upload) | |
350 { | |
351 IntSize size(2, 2); | |
352 WGC3Denum format = GraphicsContext3D::RGBA; | |
353 int pool = 1; | |
354 size_t pixelSize = textureSize(size, format); | |
355 ASSERT_EQ(16U, pixelSize); | |
356 | |
357 CCResourceProvider::ResourceId id = m_resourceProvider->createResource(pool,
size, format, CCResourceProvider::TextureUsageAny); | |
358 | |
359 uint8_t image[16] = {0}; | |
360 IntRect imageRect(IntPoint(), size); | |
361 m_resourceProvider->upload(id, image, imageRect, imageRect, IntSize()); | |
362 | |
363 for (uint8_t i = 0 ; i < pixelSize; ++i) | |
364 image[i] = i; | |
365 | |
366 uint8_t result[16] = {0}; | |
367 { | |
368 IntRect sourceRect(0, 0, 1, 1); | |
369 IntSize destOffset(0, 0); | |
370 m_resourceProvider->upload(id, image, imageRect, sourceRect, destOffset)
; | |
371 | |
372 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0, | |
373 0, 0, 0, 0, 0, 0, 0, 0}; | |
374 getResourcePixels(id, size, format, result); | |
375 EXPECT_EQ(0, memcmp(expected, result, pixelSize)); | |
376 } | |
377 { | |
378 IntRect sourceRect(0, 0, 1, 1); | |
379 IntSize destOffset(1, 1); | |
380 m_resourceProvider->upload(id, image, imageRect, sourceRect, destOffset)
; | |
381 | |
382 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0, | |
383 0, 0, 0, 0, 0, 1, 2, 3}; | |
384 getResourcePixels(id, size, format, result); | |
385 EXPECT_EQ(0, memcmp(expected, result, pixelSize)); | |
386 } | |
387 { | |
388 IntRect sourceRect(1, 0, 1, 1); | |
389 IntSize destOffset(0, 1); | |
390 m_resourceProvider->upload(id, image, imageRect, sourceRect, destOffset)
; | |
391 | |
392 uint8_t expected[16] = {0, 1, 2, 3, 0, 0, 0, 0, | |
393 4, 5, 6, 7, 0, 1, 2, 3}; | |
394 getResourcePixels(id, size, format, result); | |
395 EXPECT_EQ(0, memcmp(expected, result, pixelSize)); | |
396 } | |
397 { | |
398 IntRect offsetImageRect(IntPoint(100, 100), size); | |
399 IntRect sourceRect(100, 100, 1, 1); | |
400 IntSize destOffset(1, 0); | |
401 m_resourceProvider->upload(id, image, offsetImageRect, sourceRect, destO
ffset); | |
402 | |
403 uint8_t expected[16] = {0, 1, 2, 3, 0, 1, 2, 3, | |
404 4, 5, 6, 7, 0, 1, 2, 3}; | |
405 getResourcePixels(id, size, format, result); | |
406 EXPECT_EQ(0, memcmp(expected, result, pixelSize)); | |
407 } | |
408 | |
409 | |
410 m_resourceProvider->deleteResource(id); | |
411 } | |
412 | |
413 TEST_P(CCResourceProviderTest, TransferResources) | |
414 { | |
415 // Resource transfer is only supported with GL textures for now. | |
416 if (GetParam() != CCResourceProvider::GLTexture) | |
417 return; | |
418 | |
419 scoped_ptr<CCGraphicsContext> childContext(FakeWebCompositorOutputSurface::c
reate(ResourceProviderContext::create(m_sharedData.get()))); | |
420 OwnPtr<CCResourceProvider> childResourceProvider(CCResourceProvider::create(
childContext.get())); | |
421 | |
422 IntSize size(1, 1); | |
423 WGC3Denum format = GraphicsContext3D::RGBA; | |
424 int pool = 1; | |
425 size_t pixelSize = textureSize(size, format); | |
426 ASSERT_EQ(4U, pixelSize); | |
427 | |
428 CCResourceProvider::ResourceId id1 = childResourceProvider->createResource(p
ool, size, format, CCResourceProvider::TextureUsageAny); | |
429 uint8_t data1[4] = {1, 2, 3, 4}; | |
430 IntRect rect(IntPoint(), size); | |
431 childResourceProvider->upload(id1, data1, rect, rect, IntSize()); | |
432 | |
433 CCResourceProvider::ResourceId id2 = childResourceProvider->createResource(p
ool, size, format, CCResourceProvider::TextureUsageAny); | |
434 uint8_t data2[4] = {5, 5, 5, 5}; | |
435 childResourceProvider->upload(id2, data2, rect, rect, IntSize()); | |
436 | |
437 int childPool = 2; | |
438 int childId = m_resourceProvider->createChild(childPool); | |
439 | |
440 { | |
441 // Transfer some resources to the parent. | |
442 CCResourceProvider::ResourceIdArray resourceIdsToTransfer; | |
443 resourceIdsToTransfer.append(id1); | |
444 resourceIdsToTransfer.append(id2); | |
445 CCResourceProvider::TransferableResourceList list = childResourceProvide
r->prepareSendToParent(resourceIdsToTransfer); | |
446 EXPECT_NE(0u, list.syncPoint); | |
447 EXPECT_EQ(2u, list.resources.size()); | |
448 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id1)); | |
449 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id2)); | |
450 m_resourceProvider->receiveFromChild(childId, list); | |
451 } | |
452 | |
453 EXPECT_EQ(2u, m_resourceProvider->numResources()); | |
454 EXPECT_EQ(2u, m_resourceProvider->mailboxCount()); | |
455 CCResourceProvider::ResourceIdMap resourceMap = m_resourceProvider->getChild
ToParentMap(childId); | |
456 CCResourceProvider::ResourceId mappedId1 = resourceMap.get(id1); | |
457 CCResourceProvider::ResourceId mappedId2 = resourceMap.get(id2); | |
458 EXPECT_NE(0u, mappedId1); | |
459 EXPECT_NE(0u, mappedId2); | |
460 EXPECT_FALSE(m_resourceProvider->inUseByConsumer(id1)); | |
461 EXPECT_FALSE(m_resourceProvider->inUseByConsumer(id2)); | |
462 | |
463 uint8_t result[4] = {0}; | |
464 getResourcePixels(mappedId1, size, format, result); | |
465 EXPECT_EQ(0, memcmp(data1, result, pixelSize)); | |
466 | |
467 getResourcePixels(mappedId2, size, format, result); | |
468 EXPECT_EQ(0, memcmp(data2, result, pixelSize)); | |
469 | |
470 { | |
471 // Check that transfering again the same resource from the child to the | |
472 // parent is a noop. | |
473 CCResourceProvider::ResourceIdArray resourceIdsToTransfer; | |
474 resourceIdsToTransfer.append(id1); | |
475 CCResourceProvider::TransferableResourceList list = childResourceProvide
r->prepareSendToParent(resourceIdsToTransfer); | |
476 EXPECT_EQ(0u, list.syncPoint); | |
477 EXPECT_EQ(0u, list.resources.size()); | |
478 } | |
479 | |
480 { | |
481 // Transfer resources back from the parent to the child. | |
482 CCResourceProvider::ResourceIdArray resourceIdsToTransfer; | |
483 resourceIdsToTransfer.append(mappedId1); | |
484 resourceIdsToTransfer.append(mappedId2); | |
485 CCResourceProvider::TransferableResourceList list = m_resourceProvider->
prepareSendToChild(childId, resourceIdsToTransfer); | |
486 EXPECT_NE(0u, list.syncPoint); | |
487 EXPECT_EQ(2u, list.resources.size()); | |
488 childResourceProvider->receiveFromParent(list); | |
489 } | |
490 EXPECT_EQ(0u, m_resourceProvider->mailboxCount()); | |
491 EXPECT_EQ(2u, childResourceProvider->mailboxCount()); | |
492 EXPECT_FALSE(childResourceProvider->inUseByConsumer(id1)); | |
493 EXPECT_FALSE(childResourceProvider->inUseByConsumer(id2)); | |
494 | |
495 ResourceProviderContext* childContext3D = static_cast<ResourceProviderContex
t*>(childContext->context3D()); | |
496 { | |
497 CCResourceProvider::ScopedReadLockGL lock(childResourceProvider.get(), i
d1); | |
498 ASSERT_NE(0U, lock.textureId()); | |
499 childContext3D->bindTexture(GraphicsContext3D::TEXTURE_2D, lock.textureI
d()); | |
500 childContext3D->getPixels(size, format, result); | |
501 EXPECT_EQ(0, memcmp(data1, result, pixelSize)); | |
502 } | |
503 { | |
504 CCResourceProvider::ScopedReadLockGL lock(childResourceProvider.get(), i
d2); | |
505 ASSERT_NE(0U, lock.textureId()); | |
506 childContext3D->bindTexture(GraphicsContext3D::TEXTURE_2D, lock.textureI
d()); | |
507 childContext3D->getPixels(size, format, result); | |
508 EXPECT_EQ(0, memcmp(data2, result, pixelSize)); | |
509 } | |
510 | |
511 { | |
512 // Transfer resources to the parent again. | |
513 CCResourceProvider::ResourceIdArray resourceIdsToTransfer; | |
514 resourceIdsToTransfer.append(id1); | |
515 resourceIdsToTransfer.append(id2); | |
516 CCResourceProvider::TransferableResourceList list = childResourceProvide
r->prepareSendToParent(resourceIdsToTransfer); | |
517 EXPECT_NE(0u, list.syncPoint); | |
518 EXPECT_EQ(2u, list.resources.size()); | |
519 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id1)); | |
520 EXPECT_TRUE(childResourceProvider->inUseByConsumer(id2)); | |
521 m_resourceProvider->receiveFromChild(childId, list); | |
522 } | |
523 | |
524 EXPECT_EQ(2u, m_resourceProvider->numResources()); | |
525 m_resourceProvider->destroyChild(childId); | |
526 EXPECT_EQ(0u, m_resourceProvider->numResources()); | |
527 EXPECT_EQ(0u, m_resourceProvider->mailboxCount()); | |
528 } | |
529 | |
530 INSTANTIATE_TEST_CASE_P(CCResourceProviderTests, | |
531 CCResourceProviderTest, | |
532 ::testing::Values(CCResourceProvider::GLTexture, | |
533 CCResourceProvider::Bitmap)); | |
534 | |
535 } // namespace | |
OLD | NEW |