diff options
author | sheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-21 04:15:41 +0000 |
---|---|---|
committer | sheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-21 04:15:41 +0000 |
commit | d97626717c075142fb955b3e2429ca1c70332327 (patch) | |
tree | b6b29c273f047ef3724506abc22953955b1468bd /cc/texture_uploader_unittest.cc | |
parent | 41e269778a9d8d2e6ee4762e1d199371fac7be4a (diff) | |
download | chromium_src-d97626717c075142fb955b3e2429ca1c70332327.zip chromium_src-d97626717c075142fb955b3e2429ca1c70332327.tar.gz chromium_src-d97626717c075142fb955b3e2429ca1c70332327.tar.bz2 |
YUV software decode path stride fixes.
Fix YUV software-decoded video playback for frame with padded strides.
* Use per-plane stride info from VideoFrame for source image rect width, when
uploading a CPU-allocated video frame.
* Modify cc::TextureUploader to handle non-4-byte-aligned texture uploads.
* Add testcase UploadContentsTest to check texture upload paths.
* Add RoundDown()/RoundUp() to base::bits and use them in media::VideoFrame
and cc::TextureUploader.
BUG=chromium:160622, chromium:161023
TEST=local build, run on x86
Review URL: https://chromiumcodereview.appspot.com/11413005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168970 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/texture_uploader_unittest.cc')
-rw-r--r-- | cc/texture_uploader_unittest.cc | 166 |
1 files changed, 149 insertions, 17 deletions
diff --git a/cc/texture_uploader_unittest.cc b/cc/texture_uploader_unittest.cc index 85bc949..a975c16 100644 --- a/cc/texture_uploader_unittest.cc +++ b/cc/texture_uploader_unittest.cc @@ -16,12 +16,42 @@ using namespace WebKit; namespace cc { namespace { -class FakeWebGraphicsContext3DWithQueryTesting : public FakeWebGraphicsContext3D { +unsigned int RoundUp(unsigned int n, unsigned int mul) +{ + return (((n - 1) / mul) * mul) + mul; +} + +class FakeWebGraphicsContext3DTextureUpload : public FakeWebGraphicsContext3D { public: - FakeWebGraphicsContext3DWithQueryTesting() : m_resultAvailable(0) + FakeWebGraphicsContext3DTextureUpload() + : m_resultAvailable(0) + , m_unpackAlignment(4) { } + virtual void pixelStorei(WGC3Denum pname, WGC3Dint param) + { + switch (pname) { + case GL_UNPACK_ALIGNMENT: + // param should be a power of two <= 8 + EXPECT_EQ(0, param & (param - 1)); + EXPECT_GE(8, param); + switch (param) { + case 1: + case 2: + case 4: + case 8: + m_unpackAlignment = param; + break; + default: + break; + } + break; + default: + break; + } + } + virtual void getQueryObjectuivEXT(WebGLId, WGC3Denum type, WGC3Duint* value) { switch (type) { @@ -34,66 +64,168 @@ public: } } + virtual void texSubImage2D(WGC3Denum target, WGC3Dint level, WGC3Dint xoffset, WGC3Dint yoffset, WGC3Dsizei width, WGC3Dsizei height, WGC3Denum format, WGC3Denum type, const void* pixels) + { + EXPECT_EQ(GL_TEXTURE_2D, target); + EXPECT_EQ(0, level); + EXPECT_LE(0, width); + EXPECT_LE(0, height); + EXPECT_LE(0, xoffset); + EXPECT_LE(0, yoffset); + EXPECT_LE(0, width); + EXPECT_LE(0, height); + + // Check for allowed format/type combination. + unsigned int bytesPerPixel = 0; + switch (format) { + case GL_ALPHA: + EXPECT_EQ(GL_UNSIGNED_BYTE, type); + bytesPerPixel = 1; + break; + case GL_RGB: + EXPECT_NE(GL_UNSIGNED_SHORT_4_4_4_4, type); + EXPECT_NE(GL_UNSIGNED_SHORT_5_5_5_1, type); + switch (type) { + case GL_UNSIGNED_BYTE: + bytesPerPixel = 3; + break; + case GL_UNSIGNED_SHORT_5_6_5: + bytesPerPixel = 2; + break; + } + break; + case GL_RGBA: + EXPECT_NE(GL_UNSIGNED_SHORT_5_6_5, type); + switch (type) { + case GL_UNSIGNED_BYTE: + bytesPerPixel = 4; + break; + case GL_UNSIGNED_SHORT_4_4_4_4: + bytesPerPixel = 2; + break; + case GL_UNSIGNED_SHORT_5_5_5_1: + bytesPerPixel = 2; + break; + } + break; + case GL_LUMINANCE: + EXPECT_EQ(GL_UNSIGNED_BYTE, type); + bytesPerPixel = 1; + break; + case GL_LUMINANCE_ALPHA: + EXPECT_EQ(GL_UNSIGNED_BYTE, type); + bytesPerPixel = 2; + break; + } + + // If NULL, we aren't checking texture contents. + if (pixels == NULL) + return; + + const uint8* bytes = static_cast<const uint8*>(pixels); + // We'll expect the first byte of every row to be 0x1, and the last byte to be 0x2 + const unsigned int stride = RoundUp(bytesPerPixel * width, m_unpackAlignment); + for (WGC3Dsizei row = 0; row < height; ++row) { + const uint8* rowBytes = bytes + (xoffset * bytesPerPixel + (yoffset + row) * stride); + EXPECT_EQ(0x1, rowBytes[0]); + EXPECT_EQ(0x2, rowBytes[width * bytesPerPixel - 1]); + } + } + void setResultAvailable(unsigned resultAvailable) { m_resultAvailable = resultAvailable; } private: + unsigned m_unpackAlignment; unsigned m_resultAvailable; }; -void uploadTexture(TextureUploader* uploader) +void uploadTexture(TextureUploader* uploader, WGC3Denum format, const gfx::Size& size, const uint8* data) { - gfx::Size size(256, 256); - uploader->upload(NULL, + uploader->upload(data, gfx::Rect(gfx::Point(0, 0), size), gfx::Rect(gfx::Point(0, 0), size), gfx::Vector2d(), - GL_RGBA, + format, size); } TEST(TextureUploaderTest, NumBlockingUploads) { - scoped_ptr<FakeWebGraphicsContext3DWithQueryTesting> fakeContext(new FakeWebGraphicsContext3DWithQueryTesting); + scoped_ptr<FakeWebGraphicsContext3DTextureUpload> fakeContext(new FakeWebGraphicsContext3DTextureUpload); scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.get(), false, false); fakeContext->setResultAvailable(0); EXPECT_EQ(0, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); EXPECT_EQ(1, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); EXPECT_EQ(2, uploader->numBlockingUploads()); fakeContext->setResultAvailable(1); EXPECT_EQ(0, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); EXPECT_EQ(0, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); EXPECT_EQ(0, uploader->numBlockingUploads()); } TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) { - scoped_ptr<FakeWebGraphicsContext3DWithQueryTesting> fakeContext(new FakeWebGraphicsContext3DWithQueryTesting); + scoped_ptr<FakeWebGraphicsContext3DTextureUpload> fakeContext(new FakeWebGraphicsContext3DTextureUpload); scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.get(), false, false); fakeContext->setResultAvailable(0); EXPECT_EQ(0, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); EXPECT_EQ(2, uploader->numBlockingUploads()); uploader->markPendingUploadsAsNonBlocking(); EXPECT_EQ(0, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); EXPECT_EQ(1, uploader->numBlockingUploads()); fakeContext->setResultAvailable(1); EXPECT_EQ(0, uploader->numBlockingUploads()); - uploadTexture(uploader.get()); + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(0, 0), NULL); uploader->markPendingUploadsAsNonBlocking(); EXPECT_EQ(0, uploader->numBlockingUploads()); } +TEST(TextureUploaderTest, UploadContentsTest) +{ + scoped_ptr<FakeWebGraphicsContext3DTextureUpload> fakeContext(new FakeWebGraphicsContext3DTextureUpload); + scoped_ptr<TextureUploader> uploader = TextureUploader::create(fakeContext.get(), false, false); + uint8 buffer[256 * 256 * 4]; + + // Upload a tightly packed 256x256 RGBA texture. + memset(buffer, 0, sizeof(buffer)); + for (int i = 0; i < 256; ++i) { + // Mark the beginning and end of each row, for the test. + buffer[i * 4 * 256] = 0x1; + buffer[(i + 1) * 4 * 256 - 1] = 0x2; + } + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(256, 256), buffer); + + // Upload a tightly packed 41x43 RGBA texture. + memset(buffer, 0, sizeof(buffer)); + for (int i = 0; i < 43; ++i) { + // Mark the beginning and end of each row, for the test. + buffer[i * 4 * 41] = 0x1; + buffer[(i + 1) * 4 * 41 - 1] = 0x2; + } + uploadTexture(uploader.get(), GL_RGBA, gfx::Size(41, 43), buffer); + + // Upload a tightly packed 82x86 LUMINANCE texture. + memset(buffer, 0, sizeof(buffer)); + for (int i = 0; i < 86; ++i) { + // Mark the beginning and end of each row, for the test. + buffer[i * 1 * 82] = 0x1; + buffer[(i + 1) * 82 - 1] = 0x2; + } + uploadTexture(uploader.get(), GL_LUMINANCE, gfx::Size(82, 86), buffer); +} + } // namespace } // namespace cc |