This source file includes following definitions.
- unpack_alignment_
- PixelStorei
- GetQueryObjectuivEXT
- TexSubImage2D
- SetResultAvailable
- UploadTexture
- TEST
- TEST
- TEST
#include "cc/resources/texture_uploader.h"
#include "cc/base/util.h"
#include "cc/resources/prioritized_resource.h"
#include "gpu/command_buffer/client/gles2_interface_stub.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
namespace cc {
namespace {
class TextureUploadTestContext : public gpu::gles2::GLES2InterfaceStub {
public:
TextureUploadTestContext() : result_available_(0), unpack_alignment_(4) {}
virtual void PixelStorei(GLenum pname, GLint param) OVERRIDE {
switch (pname) {
case GL_UNPACK_ALIGNMENT:
EXPECT_EQ(0, param & (param - 1));
EXPECT_GE(8, param);
switch (param) {
case 1:
case 2:
case 4:
case 8:
unpack_alignment_ = param;
break;
default:
break;
}
break;
default:
break;
}
}
virtual void GetQueryObjectuivEXT(GLuint,
GLenum type,
GLuint* value) OVERRIDE {
switch (type) {
case GL_QUERY_RESULT_AVAILABLE_EXT:
*value = result_available_;
break;
default:
*value = 0;
break;
}
}
virtual void TexSubImage2D(GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const void* pixels) OVERRIDE {
EXPECT_EQ(static_cast<unsigned>(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);
unsigned int bytes_per_pixel = 0;
switch (format) {
case GL_ALPHA:
EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
bytes_per_pixel = 1;
break;
case GL_RGB:
EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_4_4_4_4), type);
EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_5_5_1), type);
switch (type) {
case GL_UNSIGNED_BYTE:
bytes_per_pixel = 3;
break;
case GL_UNSIGNED_SHORT_5_6_5:
bytes_per_pixel = 2;
break;
}
break;
case GL_RGBA:
EXPECT_NE(static_cast<unsigned>(GL_UNSIGNED_SHORT_5_6_5), type);
switch (type) {
case GL_UNSIGNED_BYTE:
bytes_per_pixel = 4;
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
bytes_per_pixel = 2;
break;
case GL_UNSIGNED_SHORT_5_5_5_1:
bytes_per_pixel = 2;
break;
}
break;
case GL_LUMINANCE:
EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
bytes_per_pixel = 1;
break;
case GL_LUMINANCE_ALPHA:
EXPECT_EQ(static_cast<unsigned>(GL_UNSIGNED_BYTE), type);
bytes_per_pixel = 2;
break;
}
if (pixels == NULL)
return;
const uint8* bytes = static_cast<const uint8*>(pixels);
const unsigned int stride =
RoundUp(bytes_per_pixel * width, unpack_alignment_);
for (GLsizei row = 0; row < height; ++row) {
const uint8* row_bytes =
bytes + (xoffset * bytes_per_pixel + (yoffset + row) * stride);
EXPECT_EQ(0x1, row_bytes[0]);
EXPECT_EQ(0x2, row_bytes[width * bytes_per_pixel - 1]);
}
}
void SetResultAvailable(unsigned result_available) {
result_available_ = result_available;
}
private:
unsigned result_available_;
unsigned unpack_alignment_;
DISALLOW_COPY_AND_ASSIGN(TextureUploadTestContext);
};
void UploadTexture(TextureUploader* uploader,
ResourceFormat format,
const gfx::Size& size,
const uint8* data) {
uploader->Upload(
data, gfx::Rect(size), gfx::Rect(size), gfx::Vector2d(), format, size);
}
TEST(TextureUploaderTest, NumBlockingUploads) {
TextureUploadTestContext context;
scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
context.SetResultAvailable(0);
EXPECT_EQ(0u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
EXPECT_EQ(1u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
EXPECT_EQ(2u, uploader->NumBlockingUploads());
context.SetResultAvailable(1);
EXPECT_EQ(0u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
EXPECT_EQ(0u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
EXPECT_EQ(0u, uploader->NumBlockingUploads());
}
TEST(TextureUploaderTest, MarkPendingUploadsAsNonBlocking) {
TextureUploadTestContext context;
scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
context.SetResultAvailable(0);
EXPECT_EQ(0u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
EXPECT_EQ(2u, uploader->NumBlockingUploads());
uploader->MarkPendingUploadsAsNonBlocking();
EXPECT_EQ(0u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
EXPECT_EQ(1u, uploader->NumBlockingUploads());
context.SetResultAvailable(1);
EXPECT_EQ(0u, uploader->NumBlockingUploads());
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(), NULL);
uploader->MarkPendingUploadsAsNonBlocking();
EXPECT_EQ(0u, uploader->NumBlockingUploads());
}
TEST(TextureUploaderTest, UploadContentsTest) {
TextureUploadTestContext context;
scoped_ptr<TextureUploader> uploader = TextureUploader::Create(&context);
uint8 buffer[256 * 256 * 4];
memset(buffer, 0, sizeof(buffer));
for (int i = 0; i < 256; ++i) {
buffer[i * 4 * 256] = 0x1;
buffer[(i + 1) * 4 * 256 - 1] = 0x2;
}
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(256, 256), buffer);
memset(buffer, 0, sizeof(buffer));
for (int i = 0; i < 43; ++i) {
buffer[i * 4 * 41] = 0x1;
buffer[(i + 1) * 4 * 41 - 1] = 0x2;
}
UploadTexture(uploader.get(), RGBA_8888, gfx::Size(41, 43), buffer);
memset(buffer, 0, sizeof(buffer));
for (int i = 0; i < 86; ++i) {
buffer[i * 1 * 82] = 0x1;
buffer[(i + 1) * 82 - 1] = 0x2;
}
UploadTexture(uploader.get(), LUMINANCE_8, gfx::Size(82, 86), buffer);
}
}
}