Commit 0b2958b6 authored by epenner@chromium.org's avatar epenner@chromium.org

cc: Defer texture allocation (to allow async allocations).

For textures, delay allocating until the first setPixels
or beginSetPixels. This allows us to do a combined async
allocation/upload in beginSetPixels.

BUG=161337


Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=173875

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=174035

Review URL: https://chromiumcodereview.appspot.com/11622008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@175884 0039d316-1c4b-4281-b951-d872f2087c98
parent ddf288e2
...@@ -77,8 +77,14 @@ void HeadsUpDisplayLayerImpl::willDraw(ResourceProvider* resourceProvider) ...@@ -77,8 +77,14 @@ void HeadsUpDisplayLayerImpl::willDraw(ResourceProvider* resourceProvider)
if (m_hudTexture->size() != bounds() || resourceProvider->inUseByConsumer(m_hudTexture->id())) if (m_hudTexture->size() != bounds() || resourceProvider->inUseByConsumer(m_hudTexture->id()))
m_hudTexture->Free(); m_hudTexture->Free();
if (!m_hudTexture->id()) if (!m_hudTexture->id()) {
m_hudTexture->Allocate(bounds(), GL_RGBA, ResourceProvider::TextureUsageAny); m_hudTexture->Allocate(bounds(), GL_RGBA, ResourceProvider::TextureUsageAny);
// TODO(epenner): This texture was being used before setPixels was called,
// which is now not allowed (it's an uninitialized read). This should be fixed
// and this allocateForTesting() removed.
// http://crbug.com/166784
resourceProvider->allocateForTesting(m_hudTexture->id());
}
} }
void HeadsUpDisplayLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData) void HeadsUpDisplayLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuadsData)
......
...@@ -1130,6 +1130,7 @@ private: ...@@ -1130,6 +1130,7 @@ private:
setSkipsDraw(skipsDraw); setSkipsDraw(skipsDraw);
if (!tileMissing) { if (!tileMissing) {
ResourceProvider::ResourceId resource = resourceProvider->createResource(gfx::Size(), GL_RGBA, ResourceProvider::TextureUsageAny); ResourceProvider::ResourceId resource = resourceProvider->createResource(gfx::Size(), GL_RGBA, ResourceProvider::TextureUsageAny);
resourceProvider->allocateForTesting(resource);
pushTileProperties(0, 0, resource, gfx::Rect(), false); pushTileProperties(0, 0, resource, gfx::Rect(), false);
} }
if (animating) if (animating)
...@@ -1755,6 +1756,7 @@ private: ...@@ -1755,6 +1756,7 @@ private:
, m_quadVisibleRect(5, 5, 5, 5) , m_quadVisibleRect(5, 5, 5, 5)
, m_resourceId(resourceProvider->createResource(gfx::Size(1, 1), GL_RGBA, ResourceProvider::TextureUsageAny)) , m_resourceId(resourceProvider->createResource(gfx::Size(1, 1), GL_RGBA, ResourceProvider::TextureUsageAny))
{ {
resourceProvider->allocateForTesting(m_resourceId);
setAnchorPoint(gfx::PointF(0, 0)); setAnchorPoint(gfx::PointF(0, 0));
setBounds(gfx::Size(10, 10)); setBounds(gfx::Size(10, 10));
setContentBounds(gfx::Size(10, 10)); setContentBounds(gfx::Size(10, 10));
......
...@@ -60,6 +60,7 @@ ResourceProvider::Resource::Resource() ...@@ -60,6 +60,7 @@ ResourceProvider::Resource::Resource()
, exported(false) , exported(false)
, markedForDeletion(false) , markedForDeletion(false)
, pendingSetPixels(false) , pendingSetPixels(false)
, allocated(false)
, size() , size()
, format(0) , format(0)
, filter(0) , filter(0)
...@@ -83,6 +84,7 @@ ResourceProvider::Resource::Resource(unsigned textureId, const gfx::Size& size, ...@@ -83,6 +84,7 @@ ResourceProvider::Resource::Resource(unsigned textureId, const gfx::Size& size,
, exported(false) , exported(false)
, markedForDeletion(false) , markedForDeletion(false)
, pendingSetPixels(false) , pendingSetPixels(false)
, allocated(false)
, size(size) , size(size)
, format(format) , format(format)
, filter(filter) , filter(filter)
...@@ -102,6 +104,7 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, const gfx::Size& size, GLe ...@@ -102,6 +104,7 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, const gfx::Size& size, GLe
, exported(false) , exported(false)
, markedForDeletion(false) , markedForDeletion(false)
, pendingSetPixels(false) , pendingSetPixels(false)
, allocated(false)
, size(size) , size(size)
, format(format) , format(format)
, filter(filter) , filter(filter)
...@@ -188,22 +191,19 @@ ResourceProvider::ResourceId ResourceProvider::createGLTexture(const gfx::Size& ...@@ -188,22 +191,19 @@ ResourceProvider::ResourceId ResourceProvider::createGLTexture(const gfx::Size&
DCHECK(context3d); DCHECK(context3d);
GLC(context3d, textureId = context3d->createTexture()); GLC(context3d, textureId = context3d->createTexture());
GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, textureId)); GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, textureId));
// Set texture properties. Allocation is delayed until needed.
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, texturePool)); GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, texturePool));
if (m_useTextureUsageHint && hint == TextureUsageFramebuffer) if (m_useTextureUsageHint && hint == TextureUsageFramebuffer)
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE)); GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE));
if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) {
GLenum storageFormat = textureToStorageFormat(format);
GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height()));
} else
GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, 0));
ResourceId id = m_nextId++; ResourceId id = m_nextId++;
Resource resource(textureId, size, format, GL_LINEAR); Resource resource(textureId, size, format, GL_LINEAR);
resource.allocated = false;
m_resources[id] = resource; m_resources[id] = resource;
return id; return id;
} }
...@@ -216,6 +216,7 @@ ResourceProvider::ResourceId ResourceProvider::createBitmap(const gfx::Size& siz ...@@ -216,6 +216,7 @@ ResourceProvider::ResourceId ResourceProvider::createBitmap(const gfx::Size& siz
ResourceId id = m_nextId++; ResourceId id = m_nextId++;
Resource resource(pixels, size, GL_RGBA, GL_LINEAR); Resource resource(pixels, size, GL_RGBA, GL_LINEAR);
resource.allocated = true;
m_resources[id] = resource; m_resources[id] = resource;
return id; return id;
} }
...@@ -235,6 +236,7 @@ ResourceProvider::ResourceId ResourceProvider::createResourceFromExternalTexture ...@@ -235,6 +236,7 @@ ResourceProvider::ResourceId ResourceProvider::createResourceFromExternalTexture
ResourceId id = m_nextId++; ResourceId id = m_nextId++;
Resource resource(textureId, gfx::Size(), 0, GL_LINEAR); Resource resource(textureId, gfx::Size(), 0, GL_LINEAR);
resource.external = true; resource.external = true;
resource.allocated = true;
m_resources[id] = resource; m_resources[id] = resource;
return id; return id;
} }
...@@ -267,9 +269,9 @@ void ResourceProvider::deleteResource(ResourceId id) ...@@ -267,9 +269,9 @@ void ResourceProvider::deleteResource(ResourceId id)
ResourceMap::iterator it = m_resources.find(id); ResourceMap::iterator it = m_resources.find(id);
CHECK(it != m_resources.end()); CHECK(it != m_resources.end());
Resource* resource = &it->second; Resource* resource = &it->second;
DCHECK(!resource->lockedForWrite);
DCHECK(!resource->lockForReadCount); DCHECK(!resource->lockForReadCount);
DCHECK(!resource->markedForDeletion); DCHECK(!resource->markedForDeletion);
DCHECK(resource->pendingSetPixels || !resource->lockedForWrite);
if (resource->exported) { if (resource->exported) {
resource->markedForDeletion = true; resource->markedForDeletion = true;
...@@ -333,8 +335,10 @@ void ResourceProvider::setPixels(ResourceId id, const uint8_t* image, const gfx: ...@@ -333,8 +335,10 @@ void ResourceProvider::setPixels(ResourceId id, const uint8_t* image, const gfx:
DCHECK(!resource->lockForReadCount); DCHECK(!resource->lockForReadCount);
DCHECK(!resource->external); DCHECK(!resource->external);
DCHECK(!resource->exported); DCHECK(!resource->exported);
lazyAllocate(resource);
if (resource->glId) { if (resource->glId) {
DCHECK(!resource->pendingSetPixels);
WebGraphicsContext3D* context3d = m_outputSurface->Context3D(); WebGraphicsContext3D* context3d = m_outputSurface->Context3D();
DCHECK(context3d); DCHECK(context3d);
DCHECK(m_textureUploader.get()); DCHECK(m_textureUploader.get());
...@@ -348,6 +352,7 @@ void ResourceProvider::setPixels(ResourceId id, const uint8_t* image, const gfx: ...@@ -348,6 +352,7 @@ void ResourceProvider::setPixels(ResourceId id, const uint8_t* image, const gfx:
} }
if (resource->pixels) { if (resource->pixels) {
DCHECK(resource->allocated);
DCHECK(resource->format == GL_RGBA); DCHECK(resource->format == GL_RGBA);
SkBitmap srcFull; SkBitmap srcFull;
srcFull.setConfig(SkBitmap::kARGB_8888_Config, imageRect.width(), imageRect.height()); srcFull.setConfig(SkBitmap::kARGB_8888_Config, imageRect.width(), imageRect.height());
...@@ -422,6 +427,8 @@ const ResourceProvider::Resource* ResourceProvider::lockForRead(ResourceId id) ...@@ -422,6 +427,8 @@ const ResourceProvider::Resource* ResourceProvider::lockForRead(ResourceId id)
Resource* resource = &it->second; Resource* resource = &it->second;
DCHECK(!resource->lockedForWrite); DCHECK(!resource->lockedForWrite);
DCHECK(!resource->exported); DCHECK(!resource->exported);
DCHECK(resource->allocated); // Uninitialized! Call setPixels or lockForWrite first.
resource->lockForReadCount++; resource->lockForReadCount++;
return resource; return resource;
} }
...@@ -447,6 +454,8 @@ const ResourceProvider::Resource* ResourceProvider::lockForWrite(ResourceId id) ...@@ -447,6 +454,8 @@ const ResourceProvider::Resource* ResourceProvider::lockForWrite(ResourceId id)
DCHECK(!resource->lockForReadCount); DCHECK(!resource->lockForReadCount);
DCHECK(!resource->exported); DCHECK(!resource->exported);
DCHECK(!resource->external); DCHECK(!resource->external);
lazyAllocate(resource);
resource->lockedForWrite = true; resource->lockedForWrite = true;
return resource; return resource;
} }
...@@ -683,6 +692,8 @@ void ResourceProvider::receiveFromChild(int child, const TransferableResourceLis ...@@ -683,6 +692,8 @@ void ResourceProvider::receiveFromChild(int child, const TransferableResourceLis
ResourceId id = m_nextId++; ResourceId id = m_nextId++;
Resource resource(textureId, it->size, it->format, it->filter); Resource resource(textureId, it->size, it->format, it->filter);
resource.mailbox.setName(it->mailbox.name); resource.mailbox.setName(it->mailbox.name);
// Don't allocate a texture for a child.
resource.allocated = true;
m_resources[id] = resource; m_resources[id] = resource;
childInfo.parentToChildMap[id] = it->id; childInfo.parentToChildMap[id] = it->id;
childInfo.childToParentMap[it->id] = id; childInfo.childToParentMap[it->id] = id;
...@@ -723,6 +734,7 @@ bool ResourceProvider::transferResource(WebGraphicsContext3D* context, ResourceI ...@@ -723,6 +734,7 @@ bool ResourceProvider::transferResource(WebGraphicsContext3D* context, ResourceI
DCHECK(!source->lockedForWrite); DCHECK(!source->lockedForWrite);
DCHECK(!source->lockForReadCount); DCHECK(!source->lockForReadCount);
DCHECK(!source->external || (source->external && !source->mailbox.isZero())); DCHECK(!source->external || (source->external && !source->mailbox.isZero()));
DCHECK(source->allocated);
if (source->exported) if (source->exported)
return false; return false;
resource->id = id; resource->id = id;
...@@ -870,6 +882,7 @@ void ResourceProvider::setPixelsFromBuffer(ResourceId id) ...@@ -870,6 +882,7 @@ void ResourceProvider::setPixelsFromBuffer(ResourceId id)
DCHECK(!resource->lockForReadCount); DCHECK(!resource->lockForReadCount);
DCHECK(!resource->external); DCHECK(!resource->external);
DCHECK(!resource->exported); DCHECK(!resource->exported);
lazyAllocate(resource);
if (resource->glId) { if (resource->glId) {
WebGraphicsContext3D* context3d = m_outputSurface->Context3D(); WebGraphicsContext3D* context3d = m_outputSurface->Context3D();
...@@ -931,7 +944,10 @@ void ResourceProvider::beginSetPixels(ResourceId id) ...@@ -931,7 +944,10 @@ void ResourceProvider::beginSetPixels(ResourceId id)
CHECK(it != m_resources.end()); CHECK(it != m_resources.end());
Resource* resource = &it->second; Resource* resource = &it->second;
DCHECK(!resource->pendingSetPixels); DCHECK(!resource->pendingSetPixels);
DCHECK(resource->glId || resource->allocated);
bool allocate = !resource->allocated;
resource->allocated = true;
lockForWrite(id); lockForWrite(id);
if (resource->glId) { if (resource->glId) {
...@@ -947,15 +963,27 @@ void ResourceProvider::beginSetPixels(ResourceId id) ...@@ -947,15 +963,27 @@ void ResourceProvider::beginSetPixels(ResourceId id)
context3d->beginQueryEXT( context3d->beginQueryEXT(
GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM,
resource->glUploadQueryId); resource->glUploadQueryId);
context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, if (allocate) {
0, /* level */ context3d->asyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
0, /* x */ 0, /* level */
0, /* y */ resource->format,
resource->size.width(), resource->size.width(),
resource->size.height(), resource->size.height(),
resource->format, 0, /* border */
GL_UNSIGNED_BYTE, resource->format,
NULL); GL_UNSIGNED_BYTE,
NULL);
} else {
context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
0, /* level */
0, /* x */
0, /* y */
resource->size.width(),
resource->size.height(),
resource->format,
GL_UNSIGNED_BYTE,
NULL);
}
context3d->endQueryEXT(GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM); context3d->endQueryEXT(GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM);
context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
} }
...@@ -993,4 +1021,31 @@ bool ResourceProvider::didSetPixelsComplete(ResourceId id) { ...@@ -993,4 +1021,31 @@ bool ResourceProvider::didSetPixelsComplete(ResourceId id) {
return true; return true;
} }
void ResourceProvider::allocateForTesting(ResourceId id) {
ResourceMap::iterator it = m_resources.find(id);
CHECK(it != m_resources.end());
Resource* resource = &it->second;
lazyAllocate(resource);
}
void ResourceProvider::lazyAllocate(Resource* resource) {
DCHECK(resource);
DCHECK(resource->glId || resource->allocated);
if (resource->allocated || !resource->glId)
return;
resource->allocated = true;
WebGraphicsContext3D* context3d = m_outputSurface->Context3D();
gfx::Size& size = resource->size;
GLenum format = resource->format;
GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, resource->glId));
if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) {
GLenum storageFormat = textureToStorageFormat(format);
GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height()));
} else
GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, 0));
}
} // namespace cc } // namespace cc
...@@ -236,6 +236,10 @@ public: ...@@ -236,6 +236,10 @@ public:
void beginSetPixels(ResourceId id); void beginSetPixels(ResourceId id);
bool didSetPixelsComplete(ResourceId id); bool didSetPixelsComplete(ResourceId id);
// For tests only! This prevents detecting uninitialized reads.
// Use setPixels or lockForWrite to allocate implicitly.
void allocateForTesting(ResourceId id);
private: private:
struct Resource { struct Resource {
Resource(); Resource();
...@@ -258,6 +262,7 @@ private: ...@@ -258,6 +262,7 @@ private:
bool exported; bool exported;
bool markedForDeletion; bool markedForDeletion;
bool pendingSetPixels; bool pendingSetPixels;
bool allocated;
gfx::Size size; gfx::Size size;
GLenum format; GLenum format;
// TODO(skyostil): Use a separate sampler object for filter state. // TODO(skyostil): Use a separate sampler object for filter state.
...@@ -285,6 +290,7 @@ private: ...@@ -285,6 +290,7 @@ private:
bool transferResource(WebKit::WebGraphicsContext3D*, ResourceId, TransferableResource*); bool transferResource(WebKit::WebGraphicsContext3D*, ResourceId, TransferableResource*);
void deleteResourceInternal(ResourceMap::iterator it); void deleteResourceInternal(ResourceMap::iterator it);
void lazyAllocate(Resource*);
OutputSurface* m_outputSurface; OutputSurface* m_outputSurface;
ResourceId m_nextId; ResourceId m_nextId;
......
...@@ -21,6 +21,10 @@ ...@@ -21,6 +21,10 @@
using namespace WebKit; using namespace WebKit;
using testing::Mock; using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
using testing::_;
namespace cc { namespace cc {
namespace { namespace {
...@@ -584,13 +588,15 @@ TEST_P(ResourceProviderTest, ScopedSampler) ...@@ -584,13 +588,15 @@ TEST_P(ResourceProviderTest, ScopedSampler)
int textureId = 1; int textureId = 1;
// Check that the texture gets created with the right sampler settings. // Check that the texture gets created with the right sampler settings.
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)); EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId))
.Times(2); // Once to create and once to allocate.
EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM)); EXPECT_CALL(*context, texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM));
ResourceProvider::ResourceId id = resourceProvider->createResource(size, format, ResourceProvider::TextureUsageAny); ResourceProvider::ResourceId id = resourceProvider->createResource(size, format, ResourceProvider::TextureUsageAny);
resourceProvider->allocateForTesting(id);
// Creating a sampler with the default filter should not change any texture // Creating a sampler with the default filter should not change any texture
// parameters. // parameters.
...@@ -644,6 +650,92 @@ TEST_P(ResourceProviderTest, ManagedResource) ...@@ -644,6 +650,92 @@ TEST_P(ResourceProviderTest, ManagedResource)
Mock::VerifyAndClearExpectations(context); Mock::VerifyAndClearExpectations(context);
} }
class AllocationTrackingContext3D : public FakeWebGraphicsContext3D {
public:
MOCK_METHOD0(createTexture, WebGLId());
MOCK_METHOD1(deleteTexture, void(WebGLId texture_id));
MOCK_METHOD2(bindTexture, void(WGC3Denum target, WebGLId texture));
MOCK_METHOD9(texImage2D, void(WGC3Denum target, WGC3Dint level, WGC3Denum internalformat,
WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format,
WGC3Denum type, const void* pixels));
MOCK_METHOD9(texSubImage2D, void(WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format,
WGC3Denum type, const void* pixels));
MOCK_METHOD9(asyncTexImage2DCHROMIUM, void(WGC3Denum target, WGC3Dint level, WGC3Denum internalformat,
WGC3Dsizei width, WGC3Dsizei height, WGC3Dint border, WGC3Denum format,
WGC3Denum type, const void* pixels));
MOCK_METHOD9(asyncTexSubImage2DCHROMIUM, void(WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset,
WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format,
WGC3Denum type, const void* pixels));
};
TEST_P(ResourceProviderTest, TextureAllocation)
{
// Only for GL textures.
if (GetParam() != ResourceProvider::GLTexture)
return;
scoped_ptr<WebKit::WebGraphicsContext3D> mock_context(
static_cast<WebKit::WebGraphicsContext3D*>(new NiceMock<AllocationTrackingContext3D>));
scoped_ptr<OutputSurface> outputSurface(FakeOutputSurface::Create3d(mock_context.Pass()));
gfx::Size size(2, 2);
gfx::Vector2d offset(0, 0);
gfx::Rect rect(0, 0, 2, 2);
WGC3Denum format = GL_RGBA;
ResourceProvider::ResourceId id = 0;
uint8_t pixels[16] = {0};
int textureId = 123;
AllocationTrackingContext3D* context = static_cast<AllocationTrackingContext3D*>(outputSurface->Context3D());
scoped_ptr<ResourceProvider> resourceProvider(ResourceProvider::create(outputSurface.get()));
// Lazy allocation. Don't allocate when creating the resource.
EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(1);
EXPECT_CALL(*context, texImage2D(_,_,_,_,_,_,_,_,_)).Times(0);
EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_,_,_,_,_,_,_,_,_)).Times(0);
id = resourceProvider->createResource(size, format, ResourceProvider::TextureUsageAny);
resourceProvider->deleteResource(id);
Mock::VerifyAndClearExpectations(context);
// Do allocate when we set the pixels.
EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(3);
EXPECT_CALL(*context, texImage2D(_,_,_,2,2,_,_,_,_)).Times(1);
EXPECT_CALL(*context, texSubImage2D(_,_,_,_,2,2,_,_,_)).Times(1);
id = resourceProvider->createResource(size, format, ResourceProvider::TextureUsageAny);
resourceProvider->setPixels(id, pixels, rect, rect, offset);
resourceProvider->deleteResource(id);
Mock::VerifyAndClearExpectations(context);
// Same for setPixelsFromBuffer
EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(3);
EXPECT_CALL(*context, texImage2D(_,_,_,2,2,_,_,_,_)).Times(1);
EXPECT_CALL(*context, texSubImage2D(_,_,_,_,2,2,_,_,_)).Times(1);
id = resourceProvider->createResource(size, format, ResourceProvider::TextureUsageAny);
resourceProvider->acquirePixelBuffer(id);
resourceProvider->setPixelsFromBuffer(id);
resourceProvider->releasePixelBuffer(id);
resourceProvider->deleteResource(id);
Mock::VerifyAndClearExpectations(context);
// Same for async version.
EXPECT_CALL(*context, createTexture()).WillOnce(Return(textureId));
EXPECT_CALL(*context, deleteTexture(textureId)).Times(1);
EXPECT_CALL(*context, bindTexture(GL_TEXTURE_2D, textureId)).Times(2);
EXPECT_CALL(*context, asyncTexImage2DCHROMIUM(_,_,_,2,2,_,_,_,_)).Times(1);
id = resourceProvider->createResource(size, format, ResourceProvider::TextureUsageAny);
resourceProvider->acquirePixelBuffer(id);
resourceProvider->beginSetPixels(id);
resourceProvider->releasePixelBuffer(id);
resourceProvider->deleteResource(id);
Mock::VerifyAndClearExpectations(context);
}
INSTANTIATE_TEST_CASE_P(ResourceProviderTests, INSTANTIATE_TEST_CASE_P(ResourceProviderTests,
ResourceProviderTest, ResourceProviderTest,
::testing::Values(ResourceProvider::GLTexture, ::testing::Values(ResourceProvider::GLTexture,
......
...@@ -141,9 +141,9 @@ void ResourceUpdateController::updateTexture(ResourceUpdate update) ...@@ -141,9 +141,9 @@ void ResourceUpdateController::updateTexture(ResourceUpdate update)
// is available in other shared contexts. It is important to do here // is available in other shared contexts. It is important to do here
// because the backing texture is created in one context while it is // because the backing texture is created in one context while it is
// being written to in another. // being written to in another.
m_resourceProvider->flush();
ResourceProvider::ScopedWriteLockGL lock( ResourceProvider::ScopedWriteLockGL lock(
m_resourceProvider, texture->resourceId()); m_resourceProvider, texture->resourceId());
m_resourceProvider->flush();
// Make sure ganesh uses the correct GL context. // Make sure ganesh uses the correct GL context.
paintContext->makeContextCurrent(); paintContext->makeContextCurrent();
......
...@@ -29,6 +29,7 @@ void TestRenderPass::AppendOneOfEveryQuadType( ...@@ -29,6 +29,7 @@ void TestRenderPass::AppendOneOfEveryQuadType(
gfx::Size(20, 12), gfx::Size(20, 12),
resourceProvider->bestTextureFormat(), resourceProvider->bestTextureFormat(),
ResourceProvider::TextureUsageAny); ResourceProvider::TextureUsageAny);
resourceProvider->allocateForTesting(texture_resource);
unsigned texture_id = ResourceProvider::ScopedReadLockGL( unsigned texture_id = ResourceProvider::ScopedReadLockGL(
resourceProvider, texture_resource).textureId(); resourceProvider, texture_resource).textureId();
...@@ -163,6 +164,7 @@ void TestRenderPass::AppendOneOfEveryQuadType( ...@@ -163,6 +164,7 @@ void TestRenderPass::AppendOneOfEveryQuadType(
gfx::Size(20, 12), gfx::Size(20, 12),
resourceProvider->bestTextureFormat(), resourceProvider->bestTextureFormat(),
ResourceProvider::TextureUsageAny); ResourceProvider::TextureUsageAny);
resourceProvider->allocateForTesting(planes[i].resourceId);
planes[i].size = gfx::Size(100, 100); planes[i].size = gfx::Size(100, 100);
planes[i].format = GL_LUMINANCE; planes[i].format = GL_LUMINANCE;
} }
......
...@@ -384,6 +384,7 @@ TEST_F(TextureLayerImplWithMailboxTest, testCallbackOnInUseResource) ...@@ -384,6 +384,7 @@ TEST_F(TextureLayerImplWithMailboxTest, testCallbackOnInUseResource)
provider->createResourceFromTextureMailbox( provider->createResourceFromTextureMailbox(
m_testData.m_mailbox1, m_testData.m_mailbox1,
m_testData.m_releaseMailbox1); m_testData.m_releaseMailbox1);
provider->allocateForTesting(id);
// Transfer some resources to the parent. // Transfer some resources to the parent.
ResourceProvider::ResourceIdArray resourceIdsToTransfer; ResourceProvider::ResourceIdArray resourceIdsToTransfer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment