mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
241 lines
8.5 KiB
C++
241 lines
8.5 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/program_cache.h"
|
|
|
|
#include "base/memory/scoped_ptr.h"
|
|
#include "gpu/command_buffer/service/mocks.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
using ::testing::Return;
|
|
|
|
namespace gpu {
|
|
namespace gles2 {
|
|
|
|
class NoBackendProgramCache : public ProgramCache {
|
|
public:
|
|
ProgramLoadResult LoadLinkedProgram(
|
|
GLuint /* program */,
|
|
Shader* /* shader_a */,
|
|
Shader* /* shader_b */,
|
|
const LocationMap* /* bind_attrib_location_map */,
|
|
const std::vector<std::string>& /* transform_feedback_varyings */,
|
|
GLenum /* transform_feedback_buffer_mode */,
|
|
const ShaderCacheCallback& /* callback */) override {
|
|
return PROGRAM_LOAD_SUCCESS;
|
|
}
|
|
void SaveLinkedProgram(
|
|
GLuint /* program */,
|
|
const Shader* /* shader_a */,
|
|
const Shader* /* shader_b */,
|
|
const LocationMap* /* bind_attrib_location_map */,
|
|
const std::vector<std::string>& /* transform_feedback_varyings */,
|
|
GLenum /* transform_feedback_buffer_mode */,
|
|
const ShaderCacheCallback& /* callback */) override {}
|
|
|
|
void LoadProgram(const std::string& /* program */) override {}
|
|
|
|
void ClearBackend() override {}
|
|
|
|
void SaySuccessfullyCached(const std::string& shader1,
|
|
const std::string& shader2,
|
|
std::map<std::string, GLint>* attrib_map,
|
|
const std::vector<std::string>& varyings,
|
|
GLenum buffer_mode) {
|
|
char a_sha[kHashLength];
|
|
char b_sha[kHashLength];
|
|
ComputeShaderHash(shader1, a_sha);
|
|
ComputeShaderHash(shader2, b_sha);
|
|
|
|
char sha[kHashLength];
|
|
ComputeProgramHash(a_sha,
|
|
b_sha,
|
|
attrib_map,
|
|
varyings,
|
|
buffer_mode,
|
|
sha);
|
|
const std::string shaString(sha, kHashLength);
|
|
|
|
LinkedProgramCacheSuccess(shaString);
|
|
}
|
|
|
|
void ComputeShaderHash(const std::string& shader,
|
|
char* result) const {
|
|
ProgramCache::ComputeShaderHash(shader, result);
|
|
}
|
|
|
|
void ComputeProgramHash(
|
|
const char* hashed_shader_0,
|
|
const char* hashed_shader_1,
|
|
const LocationMap* bind_attrib_location_map,
|
|
const std::vector<std::string>& transform_feedback_varyings,
|
|
GLenum transform_feedback_buffer_mode,
|
|
char* result) const {
|
|
ProgramCache::ComputeProgramHash(hashed_shader_0,
|
|
hashed_shader_1,
|
|
bind_attrib_location_map,
|
|
transform_feedback_varyings,
|
|
transform_feedback_buffer_mode,
|
|
result);
|
|
}
|
|
|
|
void Evict(const std::string& program_hash) {
|
|
ProgramCache::Evict(program_hash);
|
|
}
|
|
};
|
|
|
|
class ProgramCacheTest : public testing::Test {
|
|
public:
|
|
ProgramCacheTest() :
|
|
cache_(new NoBackendProgramCache()) { }
|
|
|
|
protected:
|
|
scoped_ptr<NoBackendProgramCache> cache_;
|
|
std::vector<std::string> varyings_;
|
|
};
|
|
|
|
TEST_F(ProgramCacheTest, LinkStatusSave) {
|
|
const std::string shader1 = "abcd1234";
|
|
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
{
|
|
std::string shader_a = shader1;
|
|
std::string shader_b = shader2;
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(
|
|
shader_a, shader_b, NULL, varyings_, GL_NONE));
|
|
cache_->SaySuccessfullyCached(shader_a, shader_b, NULL, varyings_, GL_NONE);
|
|
|
|
shader_a.clear();
|
|
shader_b.clear();
|
|
}
|
|
// make sure it was copied
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
|
|
cache_->GetLinkedProgramStatus(
|
|
shader1, shader2, NULL, varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(ProgramCacheTest, LinkUnknownOnFragmentSourceChange) {
|
|
const std::string shader1 = "abcd1234";
|
|
std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE);
|
|
|
|
shader2 = "different!";
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(ProgramCacheTest, LinkUnknownOnVertexSourceChange) {
|
|
std::string shader1 = "abcd1234";
|
|
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE);
|
|
|
|
shader1 = "different!";
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(ProgramCacheTest, StatusEviction) {
|
|
const std::string shader1 = "abcd1234";
|
|
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE);
|
|
char a_sha[ProgramCache::kHashLength];
|
|
char b_sha[ProgramCache::kHashLength];
|
|
cache_->ComputeShaderHash(shader1, a_sha);
|
|
cache_->ComputeShaderHash(shader2, b_sha);
|
|
|
|
char sha[ProgramCache::kHashLength];
|
|
cache_->ComputeProgramHash(a_sha,
|
|
b_sha,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
sha);
|
|
cache_->Evict(std::string(sha, ProgramCache::kHashLength));
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(ProgramCacheTest, EvictionWithReusedShader) {
|
|
const std::string shader1 = "abcd1234";
|
|
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
const std::string shader3 = "asbjbbjj239a";
|
|
cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE);
|
|
cache_->SaySuccessfullyCached(shader1, shader3, NULL, varyings_, GL_NONE);
|
|
|
|
char a_sha[ProgramCache::kHashLength];
|
|
char b_sha[ProgramCache::kHashLength];
|
|
char c_sha[ProgramCache::kHashLength];
|
|
cache_->ComputeShaderHash(shader1, a_sha);
|
|
cache_->ComputeShaderHash(shader2, b_sha);
|
|
cache_->ComputeShaderHash(shader3, c_sha);
|
|
|
|
char sha[ProgramCache::kHashLength];
|
|
cache_->ComputeProgramHash(a_sha,
|
|
b_sha,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
sha);
|
|
cache_->Evict(std::string(sha, ProgramCache::kHashLength));
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_NONE));
|
|
EXPECT_EQ(ProgramCache::LINK_SUCCEEDED,
|
|
cache_->GetLinkedProgramStatus(shader1, shader3, NULL,
|
|
varyings_, GL_NONE));
|
|
|
|
|
|
cache_->ComputeProgramHash(a_sha,
|
|
c_sha,
|
|
NULL,
|
|
varyings_,
|
|
GL_NONE,
|
|
sha);
|
|
cache_->Evict(std::string(sha, ProgramCache::kHashLength));
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_NONE));
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader3, NULL,
|
|
varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(ProgramCacheTest, StatusClear) {
|
|
const std::string shader1 = "abcd1234";
|
|
const std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
const std::string shader3 = "asbjbbjj239a";
|
|
cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_, GL_NONE);
|
|
cache_->SaySuccessfullyCached(shader1, shader3, NULL, varyings_, GL_NONE);
|
|
cache_->Clear();
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_NONE));
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader3, NULL,
|
|
varyings_, GL_NONE));
|
|
}
|
|
|
|
TEST_F(ProgramCacheTest, LinkUnknownOnTransformFeedbackChange) {
|
|
const std::string shader1 = "abcd1234";
|
|
std::string shader2 = "abcda sda b1~#4 bbbbb1234";
|
|
varyings_.push_back("a");
|
|
cache_->SaySuccessfullyCached(shader1, shader2, NULL, varyings_,
|
|
GL_INTERLEAVED_ATTRIBS);
|
|
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_SEPARATE_ATTRIBS));
|
|
|
|
varyings_.push_back("b");
|
|
EXPECT_EQ(ProgramCache::LINK_UNKNOWN,
|
|
cache_->GetLinkedProgramStatus(shader1, shader2, NULL,
|
|
varyings_, GL_INTERLEAVED_ATTRIBS));
|
|
}
|
|
|
|
} // namespace gles2
|
|
} // namespace gpu
|