mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
662 lines
24 KiB
C++
662 lines
24 KiB
C++
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "gpu/command_buffer/service/memory_program_cache.h"
|
|
|
|
#include "base/bind.h"
|
|
#include "gpu/command_buffer/common/gles2_cmd_format.h"
|
|
#include "gpu/command_buffer/service/gl_utils.h"
|
|
#include "gpu/command_buffer/service/gpu_service_test.h"
|
|
#include "gpu/command_buffer/service/shader_manager.h"
|
|
#include "gpu/command_buffer/service/shader_translator.h"
|
|
#include "gpu/command_buffer/service/test_helper.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "ui/gl/gl_bindings.h"
|
|
#include "ui/gl/gl_mock.h"
|
|
|
|
using ::testing::_;
|
|
using ::testing::Invoke;
|
|
using ::testing::SetArgPointee;
|
|
|
|
namespace gpu {
|
|
namespace gles2 {
|
|
|
|
class ProgramBinaryEmulator {
|
|
public:
|
|
ProgramBinaryEmulator(GLsizei length,
|
|
GLenum format,
|
|
const char* binary)
|
|
: length_(length),
|
|
format_(format),
|
|
binary_(binary) { }
|
|
|
|
void GetProgramBinary(GLuint program,
|
|
GLsizei buffer_size,
|
|
GLsizei* length,
|
|
GLenum* format,
|
|
GLvoid* binary) {
|
|
if (length) {
|
|
*length = length_;
|
|
}
|
|
*format = format_;
|
|
memcpy(binary, binary_, length_);
|
|
}
|
|
|
|
void ProgramBinary(GLuint program,
|
|
GLenum format,
|
|
const GLvoid* binary,
|
|
GLsizei length) {
|
|
// format and length are verified by matcher
|
|
EXPECT_EQ(0, memcmp(binary_, binary, length));
|
|
}
|
|
|
|
GLsizei length() const { return length_; }
|
|
GLenum format() const { return format_; }
|
|
const char* binary() const { return binary_; }
|
|
|
|
private:
|
|
GLsizei length_;
|
|
GLenum format_;
|
|
const char* binary_;
|
|
};
|
|
|
|
class MemoryProgramCacheTest : public GpuServiceTest {
|
|
public:
|
|
static const size_t kCacheSizeBytes = 1024;
|
|
static const GLuint kVertexShaderClientId = 90;
|
|
static const GLuint kVertexShaderServiceId = 100;
|
|
static const GLuint kFragmentShaderClientId = 91;
|
|
static const GLuint kFragmentShaderServiceId = 100;
|
|
|
|
MemoryProgramCacheTest()
|
|
: cache_(new MemoryProgramCache(kCacheSizeBytes)),
|
|
vertex_shader_(NULL),
|
|
fragment_shader_(NULL),
|
|
shader_cache_count_(0) { }
|
|
~MemoryProgramCacheTest() override { shader_manager_.Destroy(false); }
|
|
|
|
void ShaderCacheCb(const std::string& key, const std::string& shader) {
|
|
shader_cache_count_++;
|
|
shader_cache_shader_ = shader;
|
|
}
|
|
|
|
int32 shader_cache_count() { return shader_cache_count_; }
|
|
const std::string& shader_cache_shader() { return shader_cache_shader_; }
|
|
|
|
protected:
|
|
void SetUp() override {
|
|
GpuServiceTest::SetUpWithGLVersion("3.0", "GL_ARB_get_program_binary");
|
|
|
|
vertex_shader_ = shader_manager_.CreateShader(kVertexShaderClientId,
|
|
kVertexShaderServiceId,
|
|
GL_VERTEX_SHADER);
|
|
fragment_shader_ = shader_manager_.CreateShader(
|
|
kFragmentShaderClientId,
|
|
kFragmentShaderServiceId,
|
|
GL_FRAGMENT_SHADER);
|
|
ASSERT_TRUE(vertex_shader_ != NULL);
|
|
ASSERT_TRUE(fragment_shader_ != NULL);
|
|
AttributeMap vertex_attrib_map;
|
|
UniformMap vertex_uniform_map;
|
|
VaryingMap vertex_varying_map;
|
|
AttributeMap fragment_attrib_map;
|
|
UniformMap fragment_uniform_map;
|
|
VaryingMap fragment_varying_map;
|
|
|
|
vertex_attrib_map["a"] = TestHelper::ConstructAttribute(
|
|
GL_FLOAT_VEC2, 34, GL_LOW_FLOAT, false, "a");
|
|
vertex_uniform_map["a"] = TestHelper::ConstructUniform(
|
|
GL_FLOAT, 10, GL_MEDIUM_FLOAT, true, "a");
|
|
vertex_uniform_map["b"] = TestHelper::ConstructUniform(
|
|
GL_FLOAT_VEC3, 3114, GL_HIGH_FLOAT, true, "b");
|
|
vertex_varying_map["c"] = TestHelper::ConstructVarying(
|
|
GL_FLOAT_VEC4, 2, GL_HIGH_FLOAT, true, "c");
|
|
fragment_attrib_map["jjjbb"] = TestHelper::ConstructAttribute(
|
|
GL_FLOAT_MAT4, 1114, GL_MEDIUM_FLOAT, false, "jjjbb");
|
|
fragment_uniform_map["k"] = TestHelper::ConstructUniform(
|
|
GL_FLOAT_MAT2, 34413, GL_MEDIUM_FLOAT, true, "k");
|
|
fragment_varying_map["c"] = TestHelper::ConstructVarying(
|
|
GL_FLOAT_VEC4, 2, GL_HIGH_FLOAT, true, "c");
|
|
|
|
vertex_shader_->set_source("bbbalsldkdkdkd");
|
|
fragment_shader_->set_source("bbbal sldkdkdkas 134 ad");
|
|
|
|
TestHelper::SetShaderStates(
|
|
gl_.get(), vertex_shader_, true, NULL, NULL,
|
|
&vertex_attrib_map, &vertex_uniform_map, &vertex_varying_map,
|
|
NULL);
|
|
TestHelper::SetShaderStates(
|
|
gl_.get(), fragment_shader_, true, NULL, NULL,
|
|
&fragment_attrib_map, &fragment_uniform_map, &fragment_varying_map,
|
|
NULL);
|
|
}
|
|
|
|
void SetExpectationsForSaveLinkedProgram(
|
|
const GLint program_id,
|
|
ProgramBinaryEmulator* emulator) const {
|
|
EXPECT_CALL(*gl_.get(),
|
|
GetProgramiv(program_id, GL_PROGRAM_BINARY_LENGTH_OES, _))
|
|
.WillOnce(SetArgPointee<2>(emulator->length()));
|
|
EXPECT_CALL(*gl_.get(),
|
|
GetProgramBinary(program_id, emulator->length(), _, _, _))
|
|
.WillOnce(Invoke(emulator, &ProgramBinaryEmulator::GetProgramBinary));
|
|
}
|
|
|
|
void SetExpectationsForLoadLinkedProgram(
|
|
const GLint program_id,
|
|
ProgramBinaryEmulator* emulator) const {
|
|
EXPECT_CALL(*gl_.get(),
|
|
ProgramBinary(program_id,
|
|
emulator->format(),
|
|
_,
|
|
emulator->length()))
|
|
.WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary));
|
|
EXPECT_CALL(*gl_.get(),
|
|
GetProgramiv(program_id, GL_LINK_STATUS, _))
|
|
.WillOnce(SetArgPointee<2>(GL_TRUE));
|
|
}
|
|
|
|
void SetExpectationsForLoadLinkedProgramFailure(
|
|
const GLint program_id,
|
|
ProgramBinaryEmulator* emulator) const {
|
|
EXPECT_CALL(*gl_.get(),
|
|
ProgramBinary(program_id,
|
|
emulator->format(),
|
|
_,
|
|
emulator->length()))
|
|
.WillOnce(Invoke(emulator, &ProgramBinaryEmulator::ProgramBinary));
|
|
EXPECT_CALL(*gl_.get(),
|
|
GetProgramiv(program_id, GL_LINK_STATUS, _))
|
|
.WillOnce(SetArgPointee<2>(GL_FALSE));
|
|
}
|
|
|
|
scoped_ptr<MemoryProgramCache> cache_;
|
|
ShaderManager shader_manager_;
|
|
Shader* vertex_shader_;
|
|
Shader* fragment_shader_;
|
|
int32 shader_cache_count_;
|
|
std::string shader_cache_shader_;
|
|
std::vector<std::string> varyings_;
|
|
};
|
|
|
|
TEST_F(MemoryProgramCacheTest, CacheSave) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
|
|
vertex_shader_->last_compiled_signature(),
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
EXPECT_EQ(1, shader_cache_count());
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadProgram) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
|
|
vertex_shader_->last_compiled_signature(),
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
EXPECT_EQ(1, shader_cache_count());
|
|
|
|
cache_->Clear();
|
|
|
|
cache_->LoadProgram(shader_cache_shader());
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
|
|
vertex_shader_->last_compiled_signature(),
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, CacheLoadMatchesSave) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
EXPECT_EQ(1, shader_cache_count());
|
|
|
|
AttributeMap vertex_attrib_map = vertex_shader_->attrib_map();
|
|
UniformMap vertex_uniform_map = vertex_shader_->uniform_map();
|
|
VaryingMap vertex_varying_map = vertex_shader_->varying_map();
|
|
AttributeMap fragment_attrib_map = fragment_shader_->attrib_map();
|
|
UniformMap fragment_uniform_map = fragment_shader_->uniform_map();
|
|
VaryingMap fragment_varying_map = fragment_shader_->varying_map();
|
|
|
|
vertex_shader_->set_attrib_map(AttributeMap());
|
|
vertex_shader_->set_uniform_map(UniformMap());
|
|
vertex_shader_->set_varying_map(VaryingMap());
|
|
fragment_shader_->set_attrib_map(AttributeMap());
|
|
fragment_shader_->set_uniform_map(UniformMap());
|
|
fragment_shader_->set_varying_map(VaryingMap());
|
|
|
|
SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
|
|
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
|
|
// apparently the hash_map implementation on android doesn't have the
|
|
// equality operator
|
|
#if !defined(OS_ANDROID)
|
|
EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map());
|
|
EXPECT_EQ(vertex_uniform_map, vertex_shader_->uniform_map());
|
|
EXPECT_EQ(vertex_varying_map, vertex_shader_->varying_map());
|
|
EXPECT_EQ(fragment_attrib_map, fragment_shader_->attrib_map());
|
|
EXPECT_EQ(fragment_uniform_map, fragment_shader_->uniform_map());
|
|
EXPECT_EQ(fragment_varying_map, fragment_shader_->varying_map());
|
|
#endif
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadProgramMatchesSave) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
EXPECT_EQ(1, shader_cache_count());
|
|
|
|
AttributeMap vertex_attrib_map = vertex_shader_->attrib_map();
|
|
UniformMap vertex_uniform_map = vertex_shader_->uniform_map();
|
|
VaryingMap vertex_varying_map = vertex_shader_->varying_map();
|
|
AttributeMap fragment_attrib_map = fragment_shader_->attrib_map();
|
|
UniformMap fragment_uniform_map = fragment_shader_->uniform_map();
|
|
VaryingMap fragment_varying_map = fragment_shader_->varying_map();
|
|
|
|
vertex_shader_->set_attrib_map(AttributeMap());
|
|
vertex_shader_->set_uniform_map(UniformMap());
|
|
vertex_shader_->set_varying_map(VaryingMap());
|
|
fragment_shader_->set_attrib_map(AttributeMap());
|
|
fragment_shader_->set_uniform_map(UniformMap());
|
|
fragment_shader_->set_varying_map(VaryingMap());
|
|
|
|
SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
|
|
|
|
cache_->Clear();
|
|
cache_->LoadProgram(shader_cache_shader());
|
|
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
|
|
// apparently the hash_map implementation on android doesn't have the
|
|
// equality operator
|
|
#if !defined(OS_ANDROID)
|
|
EXPECT_EQ(vertex_attrib_map, vertex_shader_->attrib_map());
|
|
EXPECT_EQ(vertex_uniform_map, vertex_shader_->uniform_map());
|
|
EXPECT_EQ(vertex_varying_map, vertex_shader_->varying_map());
|
|
EXPECT_EQ(fragment_attrib_map, fragment_shader_->attrib_map());
|
|
EXPECT_EQ(fragment_uniform_map, fragment_shader_->uniform_map());
|
|
EXPECT_EQ(fragment_varying_map, fragment_shader_->varying_map());
|
|
#endif
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadFailOnLinkFalse) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
SetExpectationsForLoadLinkedProgramFailure(kProgramId, &emulator);
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentSource) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
const std::string vertex_orig_source = vertex_shader_->last_compiled_source();
|
|
vertex_shader_->set_source("different!");
|
|
TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
|
|
vertex_shader_->set_source(vertex_orig_source);
|
|
TestHelper::SetShaderStates(gl_.get(), vertex_shader_, true);
|
|
fragment_shader_->set_source("different!");
|
|
TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentMap) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
ProgramCache::LocationMap binding_map;
|
|
binding_map["test"] = 512;
|
|
cache_->SaveLinkedProgram(kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
&binding_map,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
binding_map["different!"] = 59;
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
&binding_map,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadFailOnDifferentTransformFeedbackVaryings) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
varyings_.push_back("test");
|
|
cache_->SaveLinkedProgram(kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_INTERLEAVED_ATTRIBS,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_SEPARATE_ATTRIBS,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
|
|
varyings_.push_back("different!");
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_FAILURE, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_INTERLEAVED_ATTRIBS,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, MemoryProgramCacheEviction) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary);
|
|
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
const int kEvictingProgramId = 11;
|
|
const GLuint kEvictingBinaryLength = kCacheSizeBytes - kBinaryLength + 1;
|
|
|
|
// save old source and modify for new program
|
|
const std::string& old_sig = fragment_shader_->last_compiled_signature();
|
|
fragment_shader_->set_source("al sdfkjdk");
|
|
TestHelper::SetShaderStates(gl_.get(), fragment_shader_, true);
|
|
|
|
scoped_ptr<char[]> bigTestBinary =
|
|
scoped_ptr<char[]>(new char[kEvictingBinaryLength]);
|
|
for (size_t i = 0; i < kEvictingBinaryLength; ++i) {
|
|
bigTestBinary[i] = i % 250;
|
|
}
|
|
ProgramBinaryEmulator emulator2(kEvictingBinaryLength,
|
|
kFormat,
|
|
bigTestBinary.get());
|
|
|
|
SetExpectationsForSaveLinkedProgram(kEvictingProgramId, &emulator2);
|
|
cache_->SaveLinkedProgram(kEvictingProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
|
|
vertex_shader_->last_compiled_signature(),
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN, cache_->GetLinkedProgramStatus(
|
|
old_sig,
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, SaveCorrectProgram) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator1(kBinaryLength, kFormat, test_binary);
|
|
|
|
vertex_shader_->set_source("different!");
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator1);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
|
|
vertex_shader_->last_compiled_signature(),
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, LoadCorrectProgram) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED, cache_->GetLinkedProgramStatus(
|
|
vertex_shader_->last_compiled_signature(),
|
|
fragment_shader_->last_compiled_signature(),
|
|
NULL, varyings_, GL_NONE));
|
|
|
|
SetExpectationsForLoadLinkedProgram(kProgramId, &emulator);
|
|
|
|
fragment_shader_->set_source("different!");
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
}
|
|
|
|
TEST_F(MemoryProgramCacheTest, OverwriteOnNewSave) {
|
|
const GLenum kFormat = 1;
|
|
const int kProgramId = 10;
|
|
const int kBinaryLength = 20;
|
|
char test_binary[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary[i] = i;
|
|
}
|
|
ProgramBinaryEmulator emulator(kBinaryLength, kFormat, test_binary);
|
|
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
|
|
char test_binary2[kBinaryLength];
|
|
for (int i = 0; i < kBinaryLength; ++i) {
|
|
test_binary2[i] = (i*2) % 250;
|
|
}
|
|
ProgramBinaryEmulator emulator2(kBinaryLength, kFormat, test_binary2);
|
|
SetExpectationsForSaveLinkedProgram(kProgramId, &emulator2);
|
|
cache_->SaveLinkedProgram(kProgramId, vertex_shader_,
|
|
fragment_shader_, NULL, varyings_, GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this)));
|
|
|
|
SetExpectationsForLoadLinkedProgram(kProgramId, &emulator2);
|
|
EXPECT_EQ(ProgramCache::PROGRAM_LOAD_SUCCESS, cache_->LoadLinkedProgram(
|
|
kProgramId,
|
|
vertex_shader_,
|
|
fragment_shader_,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
base::Bind(&MemoryProgramCacheTest::ShaderCacheCb,
|
|
base::Unretained(this))));
|
|
}
|
|
|
|
} // namespace gles2
|
|
} // namespace gpu
|