| 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 |