summaryrefslogtreecommitdiffstats
path: root/cc/texture_uploader_unittest.cc
diff options
context:
space:
mode:
authorsheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-21 04:15:41 +0000
committersheu@chromium.org <sheu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-21 04:15:41 +0000
commitd97626717c075142fb955b3e2429ca1c70332327 (patch)
treeb6b29c273f047ef3724506abc22953955b1468bd /cc/texture_uploader_unittest.cc
parent41e269778a9d8d2e6ee4762e1d199371fac7be4a (diff)
downloadchromium_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.cc166
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