<commit_before>// Copyright (c) 2013 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 "chrome/browser/invalidation/ticl_invalidation_service.h"

#include "base/prefs/pref_service.h"
#include "chrome/browser/invalidation/invalidation_service_factory.h"
#include "chrome/browser/invalidation/invalidation_service_test_template.h"
#include "chrome/browser/invalidation/profile_invalidation_auth_provider.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "components/signin/core/browser/signin_manager.h"
#include "sync/notifier/fake_invalidation_handler.h"
#include "sync/notifier/fake_invalidator.h"
#include "sync/notifier/invalidation_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace invalidation {

class TiclInvalidationServiceTestDelegate {
 public:
  TiclInvalidationServiceTestDelegate() { }

  ~TiclInvalidationServiceTestDelegate() {
    DestroyInvalidationService();
  }

  void CreateInvalidationService() {
    fake_invalidator_ = new syncer::FakeInvalidator();
    profile_.reset(new TestingProfile());
    token_service_.reset(new FakeProfileOAuth2TokenService);
    invalidation_service_.reset(new TiclInvalidationService(
        scoped_ptr<InvalidationAuthProvider>(
            new ProfileInvalidationAuthProvider(
                SigninManagerFactory::GetForProfile(profile_.get()),
                token_service_.get(),
                NULL)),
        profile_.get()));
    invalidation_service_->InitForTest(fake_invalidator_);
  }

  InvalidationService* GetInvalidationService() {
    return invalidation_service_.get();
  }

  void DestroyInvalidationService() {
    invalidation_service_->Shutdown();
  }

  void TriggerOnInvalidatorStateChange(syncer::InvalidatorState state) {
    fake_invalidator_->EmitOnInvalidatorStateChange(state);
  }

  void TriggerOnIncomingInvalidation(
      const syncer::ObjectIdInvalidationMap& invalidation_map) {
    fake_invalidator_->EmitOnIncomingInvalidation(invalidation_map);
  }

  syncer::FakeInvalidator* fake_invalidator_;  // owned by the service.
  scoped_ptr<TestingProfile> profile_;
  scoped_ptr<FakeProfileOAuth2TokenService> token_service_;
  scoped_ptr<TiclInvalidationService> invalidation_service_;
};

INSTANTIATE_TYPED_TEST_CASE_P(
    TiclInvalidationServiceTest, InvalidationServiceTest,
    TiclInvalidationServiceTestDelegate);

class TiclInvalidationServiceChannelTest : public ::testing::Test {
 public:
  TiclInvalidationServiceChannelTest() {}
  virtual ~TiclInvalidationServiceChannelTest() {}

  virtual void SetUp() OVERRIDE {
    TestingProfile::Builder builder;
    builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
                              FakeSigninManagerBase::Build);
    profile_ = builder.Build();
    fake_signin_manager_ = static_cast<SigninManagerBase*>(
        SigninManagerFactory::GetForProfile(profile_.get()));
    token_service_.reset(new FakeProfileOAuth2TokenService);

    scoped_ptr<InvalidationAuthProvider> auth_provider(
        new ProfileInvalidationAuthProvider(
            fake_signin_manager_, token_service_.get(), NULL));
    invalidation_service_.reset(
        new TiclInvalidationService(auth_provider.Pass(), profile_.get()));
    invalidation_service_->Init();
  }

  virtual void TearDown() OVERRIDE {
    invalidation_service_->Shutdown();
  }

  TiclInvalidationService::InvalidationNetworkChannel GetNetworkChannel() {
    return invalidation_service_->network_channel_type_;
  }

 protected:
  scoped_ptr<TestingProfile> profile_;
  SigninManagerBase* fake_signin_manager_;
  scoped_ptr<FakeProfileOAuth2TokenService> token_service_;
  scoped_ptr<TiclInvalidationService> invalidation_service_;
};

TEST_F(TiclInvalidationServiceChannelTest, ChannelSelectionTest) {
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  // If stars allign use GCM channel.
  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   true);
  EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel());

  // If Invalidation channel setting is not set or says false fall back to push
  // channel.
  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);

  profile_->GetPrefs()->ClearPref(prefs::kInvalidationServiceUseGCMChannel);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   false);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  // If invalidation channel setting says use GCM but GCM is not ALWAYS_ENABLED
  // then fall back to push channel.
  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   false);

  profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, false);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  // If first invalidation setting gets enabled and after that gcm setting gets
  // enabled then should still switch to GCM channel.
  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   true);
  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
  EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel());
}

}  // namespace invalidation
<commit_msg>[invalidations] Added test for RequestDetailedStatus<commit_after>// Copyright (c) 2013 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 "chrome/browser/invalidation/ticl_invalidation_service.h"

#include "base/prefs/pref_service.h"
#include "chrome/browser/invalidation/invalidation_service_factory.h"
#include "chrome/browser/invalidation/invalidation_service_test_template.h"
#include "chrome/browser/invalidation/profile_invalidation_auth_provider.h"
#include "chrome/browser/signin/fake_profile_oauth2_token_service.h"
#include "chrome/browser/signin/fake_signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_profile.h"
#include "components/signin/core/browser/signin_manager.h"
#include "sync/notifier/fake_invalidation_handler.h"
#include "sync/notifier/fake_invalidator.h"
#include "sync/notifier/invalidation_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace invalidation {

class TiclInvalidationServiceTestDelegate {
 public:
  TiclInvalidationServiceTestDelegate() { }

  ~TiclInvalidationServiceTestDelegate() {
    DestroyInvalidationService();
  }

  void CreateInvalidationService() {
    CreateUninitializedInvalidationService();
    InitializeInvalidationService();
  }

  void CreateUninitializedInvalidationService() {
    profile_.reset(new TestingProfile());
    token_service_.reset(new FakeProfileOAuth2TokenService);
    invalidation_service_.reset(new TiclInvalidationService(
        scoped_ptr<InvalidationAuthProvider>(
            new ProfileInvalidationAuthProvider(
                SigninManagerFactory::GetForProfile(profile_.get()),
                token_service_.get(),
                NULL)),
        profile_.get()));
  }

  void InitializeInvalidationService() {
    fake_invalidator_ = new syncer::FakeInvalidator();
    invalidation_service_->InitForTest(fake_invalidator_);
  }

  InvalidationService* GetInvalidationService() {
    return invalidation_service_.get();
  }

  void DestroyInvalidationService() {
    invalidation_service_->Shutdown();
  }

  void TriggerOnInvalidatorStateChange(syncer::InvalidatorState state) {
    fake_invalidator_->EmitOnInvalidatorStateChange(state);
  }

  void TriggerOnIncomingInvalidation(
      const syncer::ObjectIdInvalidationMap& invalidation_map) {
    fake_invalidator_->EmitOnIncomingInvalidation(invalidation_map);
  }

  syncer::FakeInvalidator* fake_invalidator_;  // owned by the service.
  scoped_ptr<TestingProfile> profile_;
  scoped_ptr<FakeProfileOAuth2TokenService> token_service_;
  scoped_ptr<TiclInvalidationService> invalidation_service_;
};

INSTANTIATE_TYPED_TEST_CASE_P(
    TiclInvalidationServiceTest, InvalidationServiceTest,
    TiclInvalidationServiceTestDelegate);

class TiclInvalidationServiceChannelTest : public ::testing::Test {
 public:
  TiclInvalidationServiceChannelTest() {}
  virtual ~TiclInvalidationServiceChannelTest() {}

  virtual void SetUp() OVERRIDE {
    TestingProfile::Builder builder;
    builder.AddTestingFactory(SigninManagerFactory::GetInstance(),
                              FakeSigninManagerBase::Build);
    profile_ = builder.Build();
    fake_signin_manager_ = static_cast<SigninManagerBase*>(
        SigninManagerFactory::GetForProfile(profile_.get()));
    token_service_.reset(new FakeProfileOAuth2TokenService);

    scoped_ptr<InvalidationAuthProvider> auth_provider(
        new ProfileInvalidationAuthProvider(
            fake_signin_manager_, token_service_.get(), NULL));
    invalidation_service_.reset(
        new TiclInvalidationService(auth_provider.Pass(), profile_.get()));
    invalidation_service_->Init();
  }

  virtual void TearDown() OVERRIDE {
    invalidation_service_->Shutdown();
  }

  TiclInvalidationService::InvalidationNetworkChannel GetNetworkChannel() {
    return invalidation_service_->network_channel_type_;
  }

 protected:
  scoped_ptr<TestingProfile> profile_;
  SigninManagerBase* fake_signin_manager_;
  scoped_ptr<FakeProfileOAuth2TokenService> token_service_;
  scoped_ptr<TiclInvalidationService> invalidation_service_;
};

TEST_F(TiclInvalidationServiceChannelTest, ChannelSelectionTest) {
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  // If stars allign use GCM channel.
  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   true);
  EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel());

  // If Invalidation channel setting is not set or says false fall back to push
  // channel.
  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);

  profile_->GetPrefs()->ClearPref(prefs::kInvalidationServiceUseGCMChannel);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   false);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  // If invalidation channel setting says use GCM but GCM is not ALWAYS_ENABLED
  // then fall back to push channel.
  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   false);

  profile_->GetPrefs()->ClearPref(prefs::kGCMChannelEnabled);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, false);
  EXPECT_EQ(TiclInvalidationService::PUSH_CLIENT_CHANNEL, GetNetworkChannel());

  // If first invalidation setting gets enabled and after that gcm setting gets
  // enabled then should still switch to GCM channel.
  profile_->GetPrefs()->SetBoolean(prefs::kInvalidationServiceUseGCMChannel,
                                   true);
  profile_->GetPrefs()->SetBoolean(prefs::kGCMChannelEnabled, true);
  EXPECT_EQ(TiclInvalidationService::GCM_NETWORK_CHANNEL, GetNetworkChannel());
}

namespace internal {

class FakeCallbackContainer {
  public:
    FakeCallbackContainer()
        : called_(false),
          weak_ptr_factory_(this) { }

    void FakeCallback(const base::DictionaryValue& value) {
      called_ = true;
    }

    bool called_;
    base::WeakPtrFactory<FakeCallbackContainer> weak_ptr_factory_;
};
}  // namespace internal

// Test that requesting for detailed status doesn't crash even if the
// underlying invalidator is not initialized.
TEST(TiclInvalidationServiceLoggingTest, DetailedStatusCallbacksWork) {
  scoped_ptr<TiclInvalidationServiceTestDelegate> delegate (
      new TiclInvalidationServiceTestDelegate());

  delegate->CreateUninitializedInvalidationService();
  invalidation::InvalidationService* const invalidator =
      delegate->GetInvalidationService();

  internal::FakeCallbackContainer fake_container;
  invalidator->RequestDetailedStatus(
    base::Bind(&internal::FakeCallbackContainer::FakeCallback,
               fake_container.weak_ptr_factory_.GetWeakPtr()));
  EXPECT_FALSE(fake_container.called_);

  delegate->InitializeInvalidationService();

  invalidator->RequestDetailedStatus(
    base::Bind(&internal::FakeCallbackContainer::FakeCallback,
               fake_container.weak_ptr_factory_.GetWeakPtr()));
  EXPECT_TRUE(fake_container.called_);
}
}  // namespace invalidation
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 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 <string>

#include "base/basictypes.h"
#include "chrome/browser/renderer_host/renderer_security_policy.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_job.h"
#include "testing/gtest/include/gtest/gtest.h"

class RendererSecurityPolicyTest : public testing::Test {
protected:
  // testing::Test
  virtual void SetUp() {
    // In the real world, "chrome-ui" is a handled scheme.
    URLRequest::RegisterProtocolFactory("chrome-ui",
                                        &URLRequestTestJob::Factory);
  }
  virtual void TearDown() {
    URLRequest::RegisterProtocolFactory("chrome-ui", NULL);
  }
};

static int kRendererID = 42;

TEST_F(RendererSecurityPolicyTest, IsWebSafeSchemeTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  EXPECT_TRUE(p->IsWebSafeScheme("http"));
  EXPECT_TRUE(p->IsWebSafeScheme("https"));
  EXPECT_TRUE(p->IsWebSafeScheme("ftp"));
  EXPECT_TRUE(p->IsWebSafeScheme("data"));
  EXPECT_TRUE(p->IsWebSafeScheme("feed"));
  EXPECT_TRUE(p->IsWebSafeScheme("chrome-extension"));

  EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme"));
  p->RegisterWebSafeScheme("registered-web-safe-scheme");
  EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme"));
}

TEST_F(RendererSecurityPolicyTest, IsPseudoSchemeTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  EXPECT_TRUE(p->IsPseudoScheme("about"));
  EXPECT_TRUE(p->IsPseudoScheme("javascript"));
  EXPECT_TRUE(p->IsPseudoScheme("view-source"));

  EXPECT_FALSE(p->IsPseudoScheme("registered-psuedo-scheme"));
  p->RegisterPseudoScheme("registered-psuedo-scheme");
  EXPECT_TRUE(p->IsPseudoScheme("registered-psuedo-scheme"));
}

TEST_F(RendererSecurityPolicyTest, StandardSchemesTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  // Safe
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("ftp://ftp.gnu.org/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,Hi")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID,
                               GURL("view-source:http://www.google.com/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("chrome-extension://xy/z")));

  // Dangerous
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("file:///etc/passwd")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("view-cache:http://www.google.com/")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("chrome-ui://foo/bar")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, AboutTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank")));

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutMemoryURL)));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCrashURL)));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCacheURL)));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutHangURL)));

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe")));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutMemoryURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutMemoryURL)));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutCrashURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCrashURL)));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutCacheURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCacheURL)));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutHangURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutHangURL)));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, JavaScriptTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
  p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')"));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, RegisterWebSafeSchemeTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  // Currently, "asdf" is destined for ShellExecute, so it is allowed.
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  // Once we register a ProtocolFactory for "asdf", we default to deny.
  URLRequest::RegisterProtocolFactory("asdf", &URLRequestTestJob::Factory);
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  // We can allow new schemes by adding them to the whitelist.
  p->RegisterWebSafeScheme("asdf");
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  // Cleanup.
  URLRequest::RegisterProtocolFactory("asdf", NULL);
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanServiceCommandsTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
  p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd"));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));

  // We should forget our state if we repeat a renderer id.
  p->Remove(kRendererID);
  p->Add(kRendererID);
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, ViewSource) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  // View source is determined by the embedded scheme.
  EXPECT_TRUE(p->CanRequestURL(kRendererID,
                               GURL("view-source:http://www.google.com/")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("view-source:file:///etc/passwd")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));

  p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd"));
  // View source needs to be able to request the embedded scheme.
  EXPECT_TRUE(p->CanRequestURL(kRendererID,
                               GURL("view-source:file:///etc/passwd")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanUploadFiles) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd"));
  p->GrantUploadFile(kRendererID, L"/etc/passwd");
  EXPECT_TRUE(p->CanUploadFile(kRendererID, L"/etc/passwd"));
  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow"));

  p->Remove(kRendererID);
  p->Add(kRendererID);

  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd"));
  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow"));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanServiceInspectElement) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  GURL url("chrome-ui://inspector/inspector.html");

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
  p->GrantInspectElement(kRendererID);
  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanServiceDOMUIBindings) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  GURL url("chrome-ui://thumb/http://www.google.com/");

  p->Add(kRendererID);

  EXPECT_FALSE(p->HasDOMUIBindings(kRendererID));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
  p->GrantDOMUIBindings(kRendererID);
  EXPECT_TRUE(p->HasDOMUIBindings(kRendererID));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, RemoveRace) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  GURL url("file:///etc/passwd");
  std::wstring file(L"/etc/passwd");

  p->Add(kRendererID);

  p->GrantRequestURL(kRendererID, url);
  p->GrantUploadFile(kRendererID, file);
  p->GrantDOMUIBindings(kRendererID);

  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
  EXPECT_TRUE(p->CanUploadFile(kRendererID, file));
  EXPECT_TRUE(p->HasDOMUIBindings(kRendererID));

  p->Remove(kRendererID);

  // Renderers are added and removed on the UI thread, but the policy can be
  // queried on the IO thread.  The RendererSecurityPolicy needs to be prepared
  // to answer policy questions about renderers who no longer exist.

  // In this case, we default to secure behavior.
  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
  EXPECT_FALSE(p->CanUploadFile(kRendererID, file));
  EXPECT_FALSE(p->HasDOMUIBindings(kRendererID));
}

<commit_msg>Add a missing header from r10487.<commit_after>// Copyright (c) 2006-2008 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 <string>

#include "base/basictypes.h"
#include "chrome/browser/renderer_host/renderer_security_policy.h"
#include "chrome/common/url_constants.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_test_job.h"
#include "testing/gtest/include/gtest/gtest.h"

class RendererSecurityPolicyTest : public testing::Test {
protected:
  // testing::Test
  virtual void SetUp() {
    // In the real world, "chrome-ui" is a handled scheme.
    URLRequest::RegisterProtocolFactory("chrome-ui",
                                        &URLRequestTestJob::Factory);
  }
  virtual void TearDown() {
    URLRequest::RegisterProtocolFactory("chrome-ui", NULL);
  }
};

static int kRendererID = 42;

TEST_F(RendererSecurityPolicyTest, IsWebSafeSchemeTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  EXPECT_TRUE(p->IsWebSafeScheme("http"));
  EXPECT_TRUE(p->IsWebSafeScheme("https"));
  EXPECT_TRUE(p->IsWebSafeScheme("ftp"));
  EXPECT_TRUE(p->IsWebSafeScheme("data"));
  EXPECT_TRUE(p->IsWebSafeScheme("feed"));
  EXPECT_TRUE(p->IsWebSafeScheme("chrome-extension"));

  EXPECT_FALSE(p->IsWebSafeScheme("registered-web-safe-scheme"));
  p->RegisterWebSafeScheme("registered-web-safe-scheme");
  EXPECT_TRUE(p->IsWebSafeScheme("registered-web-safe-scheme"));
}

TEST_F(RendererSecurityPolicyTest, IsPseudoSchemeTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  EXPECT_TRUE(p->IsPseudoScheme("about"));
  EXPECT_TRUE(p->IsPseudoScheme("javascript"));
  EXPECT_TRUE(p->IsPseudoScheme("view-source"));

  EXPECT_FALSE(p->IsPseudoScheme("registered-psuedo-scheme"));
  p->RegisterPseudoScheme("registered-psuedo-scheme");
  EXPECT_TRUE(p->IsPseudoScheme("registered-psuedo-scheme"));
}

TEST_F(RendererSecurityPolicyTest, StandardSchemesTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  // Safe
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("http://www.google.com/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("https://www.paypal.com/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("ftp://ftp.gnu.org/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("data:text/html,Hi")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID,
                               GURL("view-source:http://www.google.com/")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("chrome-extension://xy/z")));

  // Dangerous
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("file:///etc/passwd")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("view-cache:http://www.google.com/")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("chrome-ui://foo/bar")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, AboutTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:blank")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("about:BlAnK")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:BlAnK")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("aBouT:blank")));

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutMemoryURL)));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCrashURL)));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCacheURL)));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutHangURL)));

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("aBoUt:memory")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("about:CrASh")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("abOuT:cAChe")));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutMemoryURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutMemoryURL)));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutCrashURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCrashURL)));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutCacheURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutCacheURL)));

  p->GrantRequestURL(kRendererID, GURL(chrome::kAboutHangURL));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL(chrome::kAboutHangURL)));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, JavaScriptTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));
  p->GrantRequestURL(kRendererID, GURL("javascript:alert('xss')"));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("javascript:alert('xss')")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, RegisterWebSafeSchemeTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  // Currently, "asdf" is destined for ShellExecute, so it is allowed.
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  // Once we register a ProtocolFactory for "asdf", we default to deny.
  URLRequest::RegisterProtocolFactory("asdf", &URLRequestTestJob::Factory);
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  // We can allow new schemes by adding them to the whitelist.
  p->RegisterWebSafeScheme("asdf");
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  // Cleanup.
  URLRequest::RegisterProtocolFactory("asdf", NULL);
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("asdf:rockers")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanServiceCommandsTest) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
  p->GrantRequestURL(kRendererID, GURL("file:///etc/passwd"));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));

  // We should forget our state if we repeat a renderer id.
  p->Remove(kRendererID);
  p->Add(kRendererID);
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));
  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, ViewSource) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  // View source is determined by the embedded scheme.
  EXPECT_TRUE(p->CanRequestURL(kRendererID,
                               GURL("view-source:http://www.google.com/")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID,
                                GURL("view-source:file:///etc/passwd")));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));

  p->GrantRequestURL(kRendererID, GURL("view-source:file:///etc/passwd"));
  // View source needs to be able to request the embedded scheme.
  EXPECT_TRUE(p->CanRequestURL(kRendererID,
                               GURL("view-source:file:///etc/passwd")));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, GURL("file:///etc/passwd")));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanUploadFiles) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd"));
  p->GrantUploadFile(kRendererID, L"/etc/passwd");
  EXPECT_TRUE(p->CanUploadFile(kRendererID, L"/etc/passwd"));
  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow"));

  p->Remove(kRendererID);
  p->Add(kRendererID);

  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/passwd"));
  EXPECT_FALSE(p->CanUploadFile(kRendererID, L"/etc/shadow"));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanServiceInspectElement) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  GURL url("chrome-ui://inspector/inspector.html");

  p->Add(kRendererID);

  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
  p->GrantInspectElement(kRendererID);
  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, CanServiceDOMUIBindings) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  GURL url("chrome-ui://thumb/http://www.google.com/");

  p->Add(kRendererID);

  EXPECT_FALSE(p->HasDOMUIBindings(kRendererID));
  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
  p->GrantDOMUIBindings(kRendererID);
  EXPECT_TRUE(p->HasDOMUIBindings(kRendererID));
  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));

  p->Remove(kRendererID);
}

TEST_F(RendererSecurityPolicyTest, RemoveRace) {
  RendererSecurityPolicy* p = RendererSecurityPolicy::GetInstance();

  GURL url("file:///etc/passwd");
  std::wstring file(L"/etc/passwd");

  p->Add(kRendererID);

  p->GrantRequestURL(kRendererID, url);
  p->GrantUploadFile(kRendererID, file);
  p->GrantDOMUIBindings(kRendererID);

  EXPECT_TRUE(p->CanRequestURL(kRendererID, url));
  EXPECT_TRUE(p->CanUploadFile(kRendererID, file));
  EXPECT_TRUE(p->HasDOMUIBindings(kRendererID));

  p->Remove(kRendererID);

  // Renderers are added and removed on the UI thread, but the policy can be
  // queried on the IO thread.  The RendererSecurityPolicy needs to be prepared
  // to answer policy questions about renderers who no longer exist.

  // In this case, we default to secure behavior.
  EXPECT_FALSE(p->CanRequestURL(kRendererID, url));
  EXPECT_FALSE(p->CanUploadFile(kRendererID, file));
  EXPECT_FALSE(p->HasDOMUIBindings(kRendererID));
}

<|endoftext|>


<commit_before>// Copyright 2015 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 "chrome/browser/engagement/site_engagement_service.h"

#include "base/memory/ptr_util.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "chrome/browser/engagement/site_engagement_score.h"

// static
bool SiteEngagementService::IsEnabled() {
  return false;
}

// static
SiteEngagementService* SiteEngagementService::Get(Profile* profile) {
  return nullptr;
}

// static
double SiteEngagementService::GetScoreFromSettings(
    HostContentSettingsMap* settings,
    const GURL& origin) {
  auto clock = base::MakeUnique<base::DefaultClock>();
  return SiteEngagementScore(clock.get(), origin, settings)
      .GetScore();
}
<commit_msg>fix rebase issue<commit_after>// Copyright 2015 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 "chrome/browser/engagement/site_engagement_service.h"

#include "base/memory/ptr_util.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "chrome/browser/engagement/site_engagement_score.h"

// static
bool SiteEngagementService::IsEnabled() {
  return false;
}

// static
SiteEngagementService* SiteEngagementService::Get(Profile* profile) {
  return nullptr;
}

// static
double SiteEngagementService::GetScoreFromSettings(
    HostContentSettingsMap* settings,
    const GURL& origin) {
  auto clock = base::MakeUnique<base::DefaultClock>();
  return SiteEngagementScore(clock.get(), origin, settings).GetTotalScore();
}
<|endoftext|>


<commit_before>#ifndef PIXELBOOST_DISABLE_GRAPHICS

#include <fstream>
#include <sstream>

#include <vector>

#include "pixelboost/file/fileHelpers.h"
#include "pixelboost/graphics/camera/camera.h"
#include "pixelboost/graphics/camera/viewport.h"
#include "pixelboost/graphics/device/device.h"
#include "pixelboost/graphics/device/indexBuffer.h"
#include "pixelboost/graphics/device/program.h"
#include "pixelboost/graphics/device/texture.h"
#include "pixelboost/graphics/effect/effect.h"
#include "pixelboost/graphics/effect/manager.h"
#include "pixelboost/graphics/renderer/common/renderer.h"
#include "pixelboost/graphics/renderer/model/modelRenderer.h"

using namespace pb;

ModelRenderable::ModelRenderable(Uid entityId)
    : Renderable(entityId)
{
    _Model = "";
    _Texture = "";
    _Tint = glm::vec4(1,1,1,1);
}

ModelRenderable::~ModelRenderable()
{
}

Uid ModelRenderable::GetRenderableType()
{
    return TypeHash("model");
}

void ModelRenderable::CalculateMVP(Viewport* viewport)
{
    _MVPMatrix = viewport->GetCamera()->ViewProjectionMatrix * _Transform;
}

Effect* ModelRenderable::GetEffect()
{
    Effect* baseEffect = Renderable::GetEffect();
    if (baseEffect)
        return baseEffect;

    return Renderer::Instance()->GetEffectManager()->GetEffect("/default/effects/sprite.fx");
}

void ModelRenderable::SetModel(const std::string& model)
{
    _Model = model;
}

const std::string& ModelRenderable::GetModel()
{
    return _Model;
}

void ModelRenderable::SetTexture(const std::string& texture)
{
    _Texture = texture;
}

const std::string& ModelRenderable::GetTexture()
{
    return _Texture;
}

void ModelRenderable::SetTint(const glm::vec4& tint)
{
    _Tint = tint;
}

const glm::vec4& ModelRenderable::GetTint()
{
    return _Tint;
}

void ModelRenderable::SetTransform(const glm::mat4x4& transform)
{
    _Transform = transform;
}

const glm::mat4x4& ModelRenderable::GetTransform()
{
    return _Transform;
}

Model::Model()
    : _RefCount(1)
{

}

Model::~Model()
{
    GraphicsDevice::Instance()->DestroyIndexBuffer(_IndexBuffer);
    GraphicsDevice::Instance()->DestroyVertexBuffer(_VertexBuffer);
}

bool Model::Load(const std::string& fileName)
{
    std::string objFilename = fileName;

    FILE* file = fopen(objFilename.c_str(), "r");

    if (!file)
        return false;

    std::vector<glm::vec3> vertices;
    std::vector<glm::vec2> uvs;
    std::vector<glm::vec3> normals;

    std::vector<Vertex_NPXYZ_UV> verts;

    enum ReadMode
    {
        kReadModeVertex,
        kReadModeTexture,
        kReadModeNormal,
        kReadModeFace
    };

    ReadMode readMode;

    char lineChars[1024];
    while (!feof(file))
    {
        fgets(lineChars, 1024, file);

        std::string line = lineChars;

        std::vector<std::string> command = SplitLine(line);

        if (command.size() < 1)
            continue;

        if (command[0] == "v")
            readMode = kReadModeVertex;
        else if (command[0] == "vt")
            readMode = kReadModeTexture;
        else if (command[0] == "vn")
            readMode = kReadModeNormal;
        else if (command[0] == "f")
            readMode = kReadModeFace;
        else
            continue;

        switch (readMode)
        {
            case kReadModeVertex:
            {
                vertices.push_back(glm::vec3(atof(command[1].c_str()), atof(command[2].c_str()), atof(command[3].c_str())));
                break;
            }
            case kReadModeTexture:
            {
                uvs.push_back(glm::vec2(atof(command[1].c_str()), atof(command[2].c_str())));
                break;
            }
            case kReadModeNormal:
            {
                normals.push_back(glm::vec3(atof(command[1].c_str()), atof(command[2].c_str()), atof(command[3].c_str())));
                break;
            }
            case kReadModeFace:
            {
                // Only support triangulated faces at the moment
                if (command.size() == 4)
                {
                    ParseVert(verts, command[1], vertices, uvs, normals);
                    ParseVert(verts, command[2], vertices, uvs, normals);
                    ParseVert(verts, command[3], vertices, uvs, normals);
                }
                break;
            }
        }
    }

    fclose(file);

    _NumVertices = verts.size();

    _VertexBuffer = GraphicsDevice::Instance()->CreateVertexBuffer(kBufferFormatStatic, kVertexFormat_NP_XYZ_UV, _NumVertices);
    _VertexBuffer->Lock();
    Vertex_NPXYZ_UV* vertexBuffer = static_cast<Vertex_NPXYZ_UV*>(_VertexBuffer->GetData());
    for (int i=0; i<_NumVertices; i++)
    {
        vertexBuffer[i].position[0] = verts[i].position[0];
        vertexBuffer[i].position[1] = verts[i].position[1];
        vertexBuffer[i].position[2] = verts[i].position[2];
        vertexBuffer[i].uv[0] = verts[i].uv[0];
        vertexBuffer[i].uv[1] = verts[i].uv[1];
        vertexBuffer[i].normal[0] = verts[i].normal[0];
        vertexBuffer[i].normal[1] = verts[i].normal[1];
        vertexBuffer[i].normal[2] = verts[i].normal[2];
    }
    _VertexBuffer->Unlock();

    _IndexBuffer = GraphicsDevice::Instance()->CreateIndexBuffer(kBufferFormatStatic, _NumVertices);
    _IndexBuffer->Lock();
    unsigned short* indexBuffer = _IndexBuffer->GetData();
    for (int i=0; i<_NumVertices; i++)
    {
        indexBuffer[i] = i;
    }
    _IndexBuffer->Unlock();

	return true;
}

void Model::ParseVert(std::vector<Vertex_NPXYZ_UV>& verts, const std::string& vert, const std::vector<glm::vec3>& vertices, const std::vector<glm::vec2>& uvs, const std::vector<glm::vec3>& normals)
{
    std::vector<std::string> vertIndices = SplitPath(vert);

    if (vertIndices.size() < 3)
        return;

    int posIndex = atoi(vertIndices[0].c_str());
    int uvIndex = atoi(vertIndices[1].c_str());
    int normalIndex = atoi(vertIndices[2].c_str());

    glm::vec3 pos = vertices[posIndex-1];
    glm::vec2 uv = uvs[uvIndex-1];
    glm::vec3 normal = normals[normalIndex-1];

    Vertex_NPXYZ_UV vertex;
    vertex.position[0] = pos[0];
    vertex.position[1] = pos[1];
    vertex.position[2] = pos[2];
    vertex.uv[0] = uv[0];
    vertex.uv[1] = 1.f-uv[1];
    vertex.normal[0] = normal[0];
    vertex.normal[1] = normal[1];
    vertex.normal[2] = normal[2];

    verts.push_back(vertex);
}

std::vector<std::string>& Model::SplitString(const std::string &string, char delim, std::vector<std::string> &items)
{
    std::stringstream stream(string);
    std::string item;
    while(std::getline(stream, item, delim)) {
        items.push_back(item);
    }
    return items;
}

std::vector<std::string> Model::SplitLine(const std::string &string)
{
    std::vector<std::string> items;
    return SplitString(string, ' ', items);
}

std::vector<std::string> Model::SplitPath(const std::string &string)
{
    std::vector<std::string> items;
    return SplitString(string, '/', items);
}

ModelRenderer::ModelRenderer()
{
    Renderer::Instance()->SetHandler(TypeHash("model"), this);

    Renderer::Instance()->GetEffectManager()->LoadEffect("/default/effects/sprite.fx");
}

ModelRenderer::~ModelRenderer()
{
    Renderer::Instance()->GetEffectManager()->UnloadEffect("/default/effects/sprite.fx");

    for (ModelMap::iterator it = _Models.begin(); it != _Models.end(); ++it)
    {
        delete it->second;
    }

    for (TextureMap::iterator it = _Textures.begin(); it != _Textures.end(); ++it)
    {
        GraphicsDevice::Instance()->DestroyTexture(it->second);
    }
}

void ModelRenderer::Render(int count, Renderable** renderables, Viewport* viewport, EffectPass* effectPass)
{
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateAlphaTest, false);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateBlend, false);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateDepthTest, true);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateTexture2D, true);

    for (int i=0; i<count; i++)
    {
        ModelRenderable& renderable = *static_cast<ModelRenderable*>(renderables[i]);

        Model* model = GetModel(renderable._Model);
        Texture* texture = GetTexture(renderable._Texture);

        if (!model || !texture)
            continue;

        effectPass->GetShaderProgram()->SetUniform("modelViewProjectionMatrix", renderable.GetMVP());
        effectPass->GetShaderProgram()->SetUniform("diffuseColor", renderable._Tint);
        effectPass->GetShaderProgram()->SetUniform("diffuseTexture", 0);

        GraphicsDevice::Instance()->BindIndexBuffer(model->_IndexBuffer);
        GraphicsDevice::Instance()->BindVertexBuffer(model->_VertexBuffer);
        GraphicsDevice::Instance()->BindTexture(texture);

        GraphicsDevice::Instance()->DrawElements(GraphicsDevice::kElementTriangles, model->_NumVertices);
    }

    GraphicsDevice::Instance()->BindIndexBuffer(0);
    GraphicsDevice::Instance()->BindTexture(0);
    GraphicsDevice::Instance()->BindVertexBuffer(0);

    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateDepthTest, false);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateTexture2D, false);

}

bool ModelRenderer::LoadModel(const std::string& modelName, const std::string& fileName)
{
    ModelMap::iterator it = _Models.find(modelName);

    if (it != _Models.end())
    {
        it->second->_RefCount++;
        return true;
    }

    Model* model = new Model();
    model->Load(fileName);

    _Models[modelName] = model;

    return false;
}

bool ModelRenderer::UnloadModel(const std::string& modelName)
{
    ModelMap::iterator it = _Models.find(modelName);

    if (it == _Models.end())
        return false;

    it->second->_RefCount--;

    if (it->second->_RefCount == 0)
    {
        delete it->second;
        _Models.erase(it);
    }

    return true;
}

bool ModelRenderer::LoadTexture(const std::string& textureName, const std::string& fileName, bool createMips)
{
    TextureMap::iterator it = _Textures.find(textureName);

    if (it != _Textures.end())
    {
        return false;
    }

    Texture* texture = GraphicsDevice::Instance()->CreateTexture();
    texture->LoadFromPng(fileName, createMips);

    _Textures[textureName] = texture;

    return true;
}

bool ModelRenderer::UnloadTexture(const std::string& textureName)
{
    TextureMap::iterator it = _Textures.find(textureName);

    if (it == _Textures.end())
        return false;

    GraphicsDevice::Instance()->DestroyTexture(it->second);
    _Textures.erase(it);

    return true;
}

Model* ModelRenderer::GetModel(const std::string& modelName)
{
    ModelMap::iterator it = _Models.find(modelName);

    if (it == _Models.end())
        return 0;

    return it->second;
}

Texture* ModelRenderer::GetTexture(const std::string& textureName)
{
    TextureMap::iterator it = _Textures.find(textureName);

    if (it == _Textures.end())
        return 0;

    return it->second;
}

#endif
<commit_msg>Support quad based models<commit_after>#ifndef PIXELBOOST_DISABLE_GRAPHICS

#include <fstream>
#include <sstream>

#include <vector>

#include "pixelboost/file/fileHelpers.h"
#include "pixelboost/graphics/camera/camera.h"
#include "pixelboost/graphics/camera/viewport.h"
#include "pixelboost/graphics/device/device.h"
#include "pixelboost/graphics/device/indexBuffer.h"
#include "pixelboost/graphics/device/program.h"
#include "pixelboost/graphics/device/texture.h"
#include "pixelboost/graphics/effect/effect.h"
#include "pixelboost/graphics/effect/manager.h"
#include "pixelboost/graphics/renderer/common/renderer.h"
#include "pixelboost/graphics/renderer/model/modelRenderer.h"

using namespace pb;

ModelRenderable::ModelRenderable(Uid entityId)
    : Renderable(entityId)
{
    _Model = "";
    _Texture = "";
    _Tint = glm::vec4(1,1,1,1);
}

ModelRenderable::~ModelRenderable()
{
}

Uid ModelRenderable::GetRenderableType()
{
    return TypeHash("model");
}

void ModelRenderable::CalculateMVP(Viewport* viewport)
{
    _MVPMatrix = viewport->GetCamera()->ViewProjectionMatrix * _Transform;
}

Effect* ModelRenderable::GetEffect()
{
    Effect* baseEffect = Renderable::GetEffect();
    if (baseEffect)
        return baseEffect;

    return Renderer::Instance()->GetEffectManager()->GetEffect("/default/effects/sprite.fx");
}

void ModelRenderable::SetModel(const std::string& model)
{
    _Model = model;
}

const std::string& ModelRenderable::GetModel()
{
    return _Model;
}

void ModelRenderable::SetTexture(const std::string& texture)
{
    _Texture = texture;
}

const std::string& ModelRenderable::GetTexture()
{
    return _Texture;
}

void ModelRenderable::SetTint(const glm::vec4& tint)
{
    _Tint = tint;
}

const glm::vec4& ModelRenderable::GetTint()
{
    return _Tint;
}

void ModelRenderable::SetTransform(const glm::mat4x4& transform)
{
    _Transform = transform;
}

const glm::mat4x4& ModelRenderable::GetTransform()
{
    return _Transform;
}

Model::Model()
    : _RefCount(1)
{

}

Model::~Model()
{
    GraphicsDevice::Instance()->DestroyIndexBuffer(_IndexBuffer);
    GraphicsDevice::Instance()->DestroyVertexBuffer(_VertexBuffer);
}

bool Model::Load(const std::string& fileName)
{
    std::string objFilename = fileName;

    FILE* file = fopen(objFilename.c_str(), "r");

    if (!file)
        return false;

    std::vector<glm::vec3> vertices;
    std::vector<glm::vec2> uvs;
    std::vector<glm::vec3> normals;

    std::vector<Vertex_NPXYZ_UV> verts;

    enum ReadMode
    {
        kReadModeVertex,
        kReadModeTexture,
        kReadModeNormal,
        kReadModeFace
    };

    ReadMode readMode;

    char lineChars[1024];
    while (!feof(file))
    {
        fgets(lineChars, 1024, file);

        std::string line = lineChars;

        std::vector<std::string> command = SplitLine(line);

        if (command.size() < 1)
            continue;

        if (command[0] == "v")
            readMode = kReadModeVertex;
        else if (command[0] == "vt")
            readMode = kReadModeTexture;
        else if (command[0] == "vn")
            readMode = kReadModeNormal;
        else if (command[0] == "f")
            readMode = kReadModeFace;
        else
            continue;

        switch (readMode)
        {
            case kReadModeVertex:
            {
                vertices.push_back(glm::vec3(atof(command[1].c_str()), atof(command[2].c_str()), atof(command[3].c_str())));
                break;
            }
            case kReadModeTexture:
            {
                uvs.push_back(glm::vec2(atof(command[1].c_str()), atof(command[2].c_str())));
                break;
            }
            case kReadModeNormal:
            {
                normals.push_back(glm::vec3(atof(command[1].c_str()), atof(command[2].c_str()), atof(command[3].c_str())));
                break;
            }
            case kReadModeFace:
            {
                // Only support triangulated faces at the moment
                if (command.size() == 4)
                {
                    ParseVert(verts, command[1], vertices, uvs, normals);
                    ParseVert(verts, command[2], vertices, uvs, normals);
                    ParseVert(verts, command[3], vertices, uvs, normals);
                } else {
                    ParseVert(verts, command[1], vertices, uvs, normals);
                    ParseVert(verts, command[2], vertices, uvs, normals);
                    ParseVert(verts, command[3], vertices, uvs, normals);
                    ParseVert(verts, command[1], vertices, uvs, normals);
                    ParseVert(verts, command[3], vertices, uvs, normals);
                    ParseVert(verts, command[4], vertices, uvs, normals);
                }
                break;
            }
        }
    }

    fclose(file);

    _NumVertices = verts.size();

    _VertexBuffer = GraphicsDevice::Instance()->CreateVertexBuffer(kBufferFormatStatic, kVertexFormat_NP_XYZ_UV, _NumVertices);
    _VertexBuffer->Lock();
    Vertex_NPXYZ_UV* vertexBuffer = static_cast<Vertex_NPXYZ_UV*>(_VertexBuffer->GetData());
    for (int i=0; i<_NumVertices; i++)
    {
        vertexBuffer[i].position[0] = verts[i].position[0];
        vertexBuffer[i].position[1] = verts[i].position[1];
        vertexBuffer[i].position[2] = verts[i].position[2];
        vertexBuffer[i].uv[0] = verts[i].uv[0];
        vertexBuffer[i].uv[1] = verts[i].uv[1];
        vertexBuffer[i].normal[0] = verts[i].normal[0];
        vertexBuffer[i].normal[1] = verts[i].normal[1];
        vertexBuffer[i].normal[2] = verts[i].normal[2];
    }
    _VertexBuffer->Unlock();

    _IndexBuffer = GraphicsDevice::Instance()->CreateIndexBuffer(kBufferFormatStatic, _NumVertices);
    _IndexBuffer->Lock();
    unsigned short* indexBuffer = _IndexBuffer->GetData();
    for (int i=0; i<_NumVertices; i++)
    {
        indexBuffer[i] = i;
    }
    _IndexBuffer->Unlock();

	return true;
}

void Model::ParseVert(std::vector<Vertex_NPXYZ_UV>& verts, const std::string& vert, const std::vector<glm::vec3>& vertices, const std::vector<glm::vec2>& uvs, const std::vector<glm::vec3>& normals)
{
    std::vector<std::string> vertIndices = SplitPath(vert);

    if (vertIndices.size() < 3)
        return;

    int posIndex = atoi(vertIndices[0].c_str());
    int uvIndex = atoi(vertIndices[1].c_str());
    int normalIndex = atoi(vertIndices[2].c_str());

    glm::vec3 pos = vertices[posIndex-1];
    glm::vec2 uv = uvs[uvIndex-1];
    glm::vec3 normal = normals[normalIndex-1];

    Vertex_NPXYZ_UV vertex;
    vertex.position[0] = pos[0];
    vertex.position[1] = pos[1];
    vertex.position[2] = pos[2];
    vertex.uv[0] = uv[0];
    vertex.uv[1] = 1.f-uv[1];
    vertex.normal[0] = normal[0];
    vertex.normal[1] = normal[1];
    vertex.normal[2] = normal[2];

    verts.push_back(vertex);
}

std::vector<std::string>& Model::SplitString(const std::string &string, char delim, std::vector<std::string> &items)
{
    std::stringstream stream(string);
    std::string item;
    while(std::getline(stream, item, delim)) {
        items.push_back(item);
    }
    return items;
}

std::vector<std::string> Model::SplitLine(const std::string &string)
{
    std::vector<std::string> items;
    return SplitString(string, ' ', items);
}

std::vector<std::string> Model::SplitPath(const std::string &string)
{
    std::vector<std::string> items;
    return SplitString(string, '/', items);
}

ModelRenderer::ModelRenderer()
{
    Renderer::Instance()->SetHandler(TypeHash("model"), this);

    Renderer::Instance()->GetEffectManager()->LoadEffect("/default/effects/sprite.fx");
}

ModelRenderer::~ModelRenderer()
{
    Renderer::Instance()->GetEffectManager()->UnloadEffect("/default/effects/sprite.fx");

    for (ModelMap::iterator it = _Models.begin(); it != _Models.end(); ++it)
    {
        delete it->second;
    }

    for (TextureMap::iterator it = _Textures.begin(); it != _Textures.end(); ++it)
    {
        GraphicsDevice::Instance()->DestroyTexture(it->second);
    }
}

void ModelRenderer::Render(int count, Renderable** renderables, Viewport* viewport, EffectPass* effectPass)
{
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateAlphaTest, false);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateBlend, false);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateDepthTest, true);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateTexture2D, true);

    for (int i=0; i<count; i++)
    {
        ModelRenderable& renderable = *static_cast<ModelRenderable*>(renderables[i]);

        Model* model = GetModel(renderable._Model);
        Texture* texture = GetTexture(renderable._Texture);

        if (!model || !texture)
            continue;

        effectPass->GetShaderProgram()->SetUniform("modelViewProjectionMatrix", renderable.GetMVP());
        effectPass->GetShaderProgram()->SetUniform("diffuseColor", renderable._Tint);
        effectPass->GetShaderProgram()->SetUniform("diffuseTexture", 0);

        GraphicsDevice::Instance()->BindIndexBuffer(model->_IndexBuffer);
        GraphicsDevice::Instance()->BindVertexBuffer(model->_VertexBuffer);
        GraphicsDevice::Instance()->BindTexture(texture);

        GraphicsDevice::Instance()->DrawElements(GraphicsDevice::kElementTriangles, model->_NumVertices);
    }

    GraphicsDevice::Instance()->BindIndexBuffer(0);
    GraphicsDevice::Instance()->BindTexture(0);
    GraphicsDevice::Instance()->BindVertexBuffer(0);

    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateDepthTest, false);
    GraphicsDevice::Instance()->SetState(GraphicsDevice::kStateTexture2D, false);

}

bool ModelRenderer::LoadModel(const std::string& modelName, const std::string& fileName)
{
    ModelMap::iterator it = _Models.find(modelName);

    if (it != _Models.end())
    {
        it->second->_RefCount++;
        return true;
    }

    Model* model = new Model();
    model->Load(fileName);

    _Models[modelName] = model;

    return false;
}

bool ModelRenderer::UnloadModel(const std::string& modelName)
{
    ModelMap::iterator it = _Models.find(modelName);

    if (it == _Models.end())
        return false;

    it->second->_RefCount--;

    if (it->second->_RefCount == 0)
    {
        delete it->second;
        _Models.erase(it);
    }

    return true;
}

bool ModelRenderer::LoadTexture(const std::string& textureName, const std::string& fileName, bool createMips)
{
    TextureMap::iterator it = _Textures.find(textureName);

    if (it != _Textures.end())
    {
        return false;
    }

    Texture* texture = GraphicsDevice::Instance()->CreateTexture();
    texture->LoadFromPng(fileName, createMips);

    _Textures[textureName] = texture;

    return true;
}

bool ModelRenderer::UnloadTexture(const std::string& textureName)
{
    TextureMap::iterator it = _Textures.find(textureName);

    if (it == _Textures.end())
        return false;

    GraphicsDevice::Instance()->DestroyTexture(it->second);
    _Textures.erase(it);

    return true;
}

Model* ModelRenderer::GetModel(const std::string& modelName)
{
    ModelMap::iterator it = _Models.find(modelName);

    if (it == _Models.end())
        return 0;

    return it->second;
}

Texture* ModelRenderer::GetTexture(const std::string& textureName)
{
    TextureMap::iterator it = _Textures.find(textureName);

    if (it == _Textures.end())
        return 0;

    return it->second;
}

#endif
<|endoftext|>


<commit_before>#include "gtest/gtest.h"

#include "Grid.hpp"

namespace {
    const int width=10, height=10;
}

namespace jakway_antf
{

/**
 * Make sure regular begin()/end() iterator looping syntax and
 * C++11 for-each syntax works
 */
TEST(GridIteratorTests, testIteratorSyntax)
{
   Grid grid(width, height);

   //give the grid a predictable pattern: every other tile is alive
   //the first tile will be alive
   bool alive = true;
   for(POS_TYPE y = 0; y < grid.getWidth(); y++)
   {
       for(POS_TYPE x = 0; x < grid.getHeight(); x++)
       {
            grid.setTile(x, y, alive);
            alive = !alive;
       }
   }

   //regular iterator syntax OK
   alive = true;
   for(Grid::GridIterator it = grid.begin(); it != grid.end(); it++)
   {
        bool tileValue = *it;
        ASSERT_TRUE(alive == tileValue);
        alive = !alive;
   }

   alive = true;
   //C++11 for-each loop OK
   for(bool tileValue : grid)
   {
        ASSERT_TRUE(alive == tileValue);
        alive = !alive;
   }
}

/**
 * make sure we actually iterate through every tile
 */
TEST(GridIteratorTests, testIteratorCount)
{
    Grid grid(width, height);

    //loop through the grid and make sure we iterate the correct number of times
    POS_TYPE i = 0;
    for(bool tile : grid)
    {
        i++;
    }

    ASSERT_TRUE(i == grid.getSize());
}

TEST(GridIteratorTests, testOutOfBounds)
{
    Grid grid(width, height);

    //an exception out to be thrown when dereferencing an iterator outside of the grid
    bool exceptionThrown = false;
    auto it = grid.end();
    try
    {
        *it;
    }
    catch(std::out_of_range)
    {
       exceptionThrown = true;
    }
    ASSERT_TRUE(exceptionThrown);
}

/**
 * try iterating through a very large grid
 */
TEST(GridIteratorTests, testHugeGrid)
{
    const POS_TYPE hugeWidth = 1000, hugeHeight = 1000;
    Grid hugeGrid(hugeWidth, hugeHeight);

    ASSERT_TRUE(hugeGrid.getSize() == (hugeWidth * hugeHeight));
    POS_TYPE i = 0;
    for(auto n : hugeGrid)
    {
        i++;
    }

    ASSERT_TRUE(i == hugeGrid.getSize());
}

//tests iterating over non-square grids
TEST(GridIteratorTests, testTallGrid)
{
    const int tallWidth = 488, tallHeight = 923;
    Grid grid(tallWidth, tallHeight);

    int i = 0;
    for(auto n : grid)
    {
        i++;
    }
    ASSERT_TRUE(i == grid.getSize());
}
TEST(GridIteratorTests, testWideGrid)
{
    const POS_TYPE wideWidth = 873, wideHeight = 111;
    Grid grid(wideWidth, wideHeight);

    POS_TYPE i = 0;
    for(auto n : grid)
    {
        i++;
    }
    ASSERT_TRUE(i == grid.getSize());
}

}
<commit_msg>included Types<commit_after>#include "gtest/gtest.h"

#include "Grid.hpp"
#include "Types.hpp"

namespace {
    const int width=10, height=10;
}

namespace jakway_antf
{

/**
 * Make sure regular begin()/end() iterator looping syntax and
 * C++11 for-each syntax works
 */
TEST(GridIteratorTests, testIteratorSyntax)
{
   Grid grid(width, height);

   //give the grid a predictable pattern: every other tile is alive
   //the first tile will be alive
   bool alive = true;
   for(POS_TYPE y = 0; y < grid.getWidth(); y++)
   {
       for(POS_TYPE x = 0; x < grid.getHeight(); x++)
       {
            grid.setTile(x, y, alive);
            alive = !alive;
       }
   }

   //regular iterator syntax OK
   alive = true;
   for(Grid::GridIterator it = grid.begin(); it != grid.end(); it++)
   {
        bool tileValue = *it;
        ASSERT_TRUE(alive == tileValue);
        alive = !alive;
   }

   alive = true;
   //C++11 for-each loop OK
   for(bool tileValue : grid)
   {
        ASSERT_TRUE(alive == tileValue);
        alive = !alive;
   }
}

/**
 * make sure we actually iterate through every tile
 */
TEST(GridIteratorTests, testIteratorCount)
{
    Grid grid(width, height);

    //loop through the grid and make sure we iterate the correct number of times
    POS_TYPE i = 0;
    for(bool tile : grid)
    {
        i++;
    }

    ASSERT_TRUE(i == grid.getSize());
}

TEST(GridIteratorTests, testOutOfBounds)
{
    Grid grid(width, height);

    //an exception out to be thrown when dereferencing an iterator outside of the grid
    bool exceptionThrown = false;
    auto it = grid.end();
    try
    {
        *it;
    }
    catch(std::out_of_range)
    {
       exceptionThrown = true;
    }
    ASSERT_TRUE(exceptionThrown);
}

/**
 * try iterating through a very large grid
 */
TEST(GridIteratorTests, testHugeGrid)
{
    const POS_TYPE hugeWidth = 1000, hugeHeight = 1000;
    Grid hugeGrid(hugeWidth, hugeHeight);

    ASSERT_TRUE(hugeGrid.getSize() == (hugeWidth * hugeHeight));
    POS_TYPE i = 0;
    for(auto n : hugeGrid)
    {
        i++;
    }

    ASSERT_TRUE(i == hugeGrid.getSize());
}

//tests iterating over non-square grids
TEST(GridIteratorTests, testTallGrid)
{
    const int tallWidth = 488, tallHeight = 923;
    Grid grid(tallWidth, tallHeight);

    int i = 0;
    for(auto n : grid)
    {
        i++;
    }
    ASSERT_TRUE(i == grid.getSize());
}
TEST(GridIteratorTests, testWideGrid)
{
    const POS_TYPE wideWidth = 873, wideHeight = 111;
    Grid grid(wideWidth, wideHeight);

    POS_TYPE i = 0;
    for(auto n : grid)
    {
        i++;
    }
    ASSERT_TRUE(i == grid.getSize());
}

}
<|endoftext|>


<commit_before>// RUN: c-index-test core -print-source-symbols -- -fms-extensions -fno-ms-compatibility %s | FileCheck %s

// CHECK: [[@LINE+1]]:8 | struct/C++ | Simple | [[Simple_USR:.*]] | <no-cgname> | Def | rel: 0
struct Simple {
  int GetX() const;
  // CHECK: [[@LINE-1]]:7 | instance-method/C++ | GetX | [[GetX_USR:.*]] | __ZNK6Simple4GetXEv | Decl,RelChild | rel: 1
  // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]

  void PutX(int i);
  // CHECK: [[@LINE-1]]:8 | instance-method/C++ | PutX | [[PutX_USR:.*]] | __ZN6Simple4PutXEi | Decl,RelChild | rel: 1
  // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]

  __declspec(property(get=GetX, put=PutX)) int propX;
  // CHECK: [[@LINE-1]]:48 | instance-property/C++ | propX | [[propX_USR:.*]] | <no-cgname> | Def,RelChild | rel: 1
  // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]
};

// CHECK: [[@LINE+1]]:5 | function/C | test | [[test_USR:.*]] | __Z4testv | Def | rel: 0
int test() {
  Simple s;
  s.propX = 5;
  // CHECK: [[@LINE-1]]:5 | instance-property/C++ | propX | [[propX_USR]] | <no-cgname> | Ref,RelCont | rel: 1
  // CHECK-NEXT: RelCont | test | [[test_USR]]
  // CHECK: [[@LINE-3]]:5 | instance-method/C++ | PutX | [[PutX_USR]] | __ZN6Simple4PutXEi | Ref,Call,RelCall,RelCont | rel: 1
  // CHECK-NEXT: RelCall,RelCont | test | [[test_USR]]

  return s.propX;
  // CHECK: [[@LINE-1]]:12 | instance-property/C++ | propX | [[propX_USR]] | <no-cgname> | Ref,RelCont | rel: 1
  // CHECK-NEXT: RelCont | test | [[test_USR]]
  // CHECK: [[@LINE-3]]:12 | instance-method/C++ | GetX | [[GetX_USR]] | __ZNK6Simple4GetXEv | Ref,Call,RelCall,RelCont | rel: 1
  // CHECK-NEXT: RelCall,RelCont | test | [[test_USR]]
}
<commit_msg>[index] Fixup for r354942. Specify target in test to achieve stable mangling.<commit_after>// RUN: c-index-test core -print-source-symbols -- -target x86_64-apple-darwin10 -fms-extensions -fno-ms-compatibility %s | FileCheck %s

// CHECK: [[@LINE+1]]:8 | struct/C++ | Simple | [[Simple_USR:.*]] | <no-cgname> | Def | rel: 0
struct Simple {
  int GetX() const;
  // CHECK: [[@LINE-1]]:7 | instance-method/C++ | GetX | [[GetX_USR:.*]] | __ZNK6Simple4GetXEv | Decl,RelChild | rel: 1
  // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]

  void PutX(int i);
  // CHECK: [[@LINE-1]]:8 | instance-method/C++ | PutX | [[PutX_USR:.*]] | __ZN6Simple4PutXEi | Decl,RelChild | rel: 1
  // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]

  __declspec(property(get=GetX, put=PutX)) int propX;
  // CHECK: [[@LINE-1]]:48 | instance-property/C++ | propX | [[propX_USR:.*]] | <no-cgname> | Def,RelChild | rel: 1
  // CHECK-NEXT: RelChild | Simple | [[Simple_USR]]
};

// CHECK: [[@LINE+1]]:5 | function/C | test | [[test_USR:.*]] | __Z4testv | Def | rel: 0
int test() {
  Simple s;
  s.propX = 5;
  // CHECK: [[@LINE-1]]:5 | instance-property/C++ | propX | [[propX_USR]] | <no-cgname> | Ref,RelCont | rel: 1
  // CHECK-NEXT: RelCont | test | [[test_USR]]
  // CHECK: [[@LINE-3]]:5 | instance-method/C++ | PutX | [[PutX_USR]] | __ZN6Simple4PutXEi | Ref,Call,RelCall,RelCont | rel: 1
  // CHECK-NEXT: RelCall,RelCont | test | [[test_USR]]

  return s.propX;
  // CHECK: [[@LINE-1]]:12 | instance-property/C++ | propX | [[propX_USR]] | <no-cgname> | Ref,RelCont | rel: 1
  // CHECK-NEXT: RelCont | test | [[test_USR]]
  // CHECK: [[@LINE-3]]:12 | instance-method/C++ | GetX | [[GetX_USR]] | __ZNK6Simple4GetXEv | Ref,Call,RelCall,RelCont | rel: 1
  // CHECK-NEXT: RelCall,RelCont | test | [[test_USR]]
}
<|endoftext|>


<commit_before>//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#ifndef GFLAGS
#include <cstdio>
int main() {
  fprintf(stderr, "Please install gflags to run rocksdb tools\n");
  return 1;
}
#else

#include <gflags/gflags.h>

#include "rocksdb/env.h"
#include "util/histogram.h"
#include "util/testharness.h"
#include "util/testutil.h"

using GFLAGS::ParseCommandLineFlags;
using GFLAGS::SetUsageMessage;

// A simple benchmark to simulate transactional logs

DEFINE_int32(num_records, 6000, "Number of records.");
DEFINE_int32(record_size, 249, "Size of each record.");
DEFINE_int32(record_interval, 10000, "Interval between records (microSec)");
DEFINE_int32(bytes_per_sync, 0, "bytes_per_sync parameter in EnvOptions");
DEFINE_bool(enable_sync, false, "sync after each write.");

namespace rocksdb {
void RunBenchmark() {
  std::string file_name = test::TmpDir() + "/log_write_benchmark.log";
  Env* env = Env::Default();
  EnvOptions env_options;
  env_options.use_mmap_writes = false;
  env_options.bytes_per_sync = FLAGS_bytes_per_sync;
  unique_ptr<WritableFile> file;
  env->NewWritableFile(file_name, &file, env_options);

  std::string record;
  record.assign(FLAGS_record_size, 'X');

  HistogramImpl hist;

  uint64_t start_time = env->NowMicros();
  for (int i = 0; i < FLAGS_num_records; i++) {
    uint64_t start_nanos = env->NowNanos();
    file->Append(record);
    file->Flush();
    if (FLAGS_enable_sync) {
      file->Sync();
    }
    hist.Add(env->NowNanos() - start_nanos);

    if (i % 1000 == 1) {
      fprintf(stderr, "Wrote %d records...\n", i);
    }

    int time_to_sleep =
        (i + 1) * FLAGS_record_interval - (env->NowMicros() - start_time);
    if (time_to_sleep > 0) {
      env->SleepForMicroseconds(time_to_sleep);
    }
  }

  fprintf(stderr, "Distribution of latency of append+flush: \n%s",
          hist.ToString().c_str());
}
}  // namespace rocksdb

int main(int argc, char** argv) {
  SetUsageMessage(std::string("\nUSAGE:\n") + std::string(argv[0]) +
                  " [OPTIONS]...");
  ParseCommandLineFlags(&argc, &argv, true);

  rocksdb::RunBenchmark();
  return 0;
}

#endif  // GFLAGS
<commit_msg>Fix log_write_bench -bytes_per_sync option. (#1375)<commit_after>//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.

#ifndef GFLAGS
#include <cstdio>
int main() {
  fprintf(stderr, "Please install gflags to run rocksdb tools\n");
  return 1;
}
#else

#include <gflags/gflags.h>

#include "rocksdb/env.h"
#include "util/file_reader_writer.h"
#include "util/histogram.h"
#include "util/testharness.h"
#include "util/testutil.h"

using GFLAGS::ParseCommandLineFlags;
using GFLAGS::SetUsageMessage;

// A simple benchmark to simulate transactional logs

DEFINE_int32(num_records, 6000, "Number of records.");
DEFINE_int32(record_size, 249, "Size of each record.");
DEFINE_int32(record_interval, 10000, "Interval between records (microSec)");
DEFINE_int32(bytes_per_sync, 0, "bytes_per_sync parameter in EnvOptions");
DEFINE_bool(enable_sync, false, "sync after each write.");

namespace rocksdb {
void RunBenchmark() {
  std::string file_name = test::TmpDir() + "/log_write_benchmark.log";
  Env* env = Env::Default();
  EnvOptions env_options;
  env_options.use_mmap_writes = false;
  env_options.bytes_per_sync = FLAGS_bytes_per_sync;
  unique_ptr<WritableFile> file;
  env->NewWritableFile(file_name, &file, env_options);
  unique_ptr<WritableFileWriter> writer;
  writer.reset(new WritableFileWriter(std::move(file), env_options));

  std::string record;
  record.assign(FLAGS_record_size, 'X');

  HistogramImpl hist;

  uint64_t start_time = env->NowMicros();
  for (int i = 0; i < FLAGS_num_records; i++) {
    uint64_t start_nanos = env->NowNanos();
    writer->Append(record);
    writer->Flush();
    if (FLAGS_enable_sync) {
      writer->Sync(false);
    }
    hist.Add(env->NowNanos() - start_nanos);

    if (i % 1000 == 1) {
      fprintf(stderr, "Wrote %d records...\n", i);
    }

    int time_to_sleep =
        (i + 1) * FLAGS_record_interval - (env->NowMicros() - start_time);
    if (time_to_sleep > 0) {
      env->SleepForMicroseconds(time_to_sleep);
    }
  }

  fprintf(stderr, "Distribution of latency of append+flush: \n%s",
          hist.ToString().c_str());
}
}  // namespace rocksdb

int main(int argc, char** argv) {
  SetUsageMessage(std::string("\nUSAGE:\n") + std::string(argv[0]) +
                  " [OPTIONS]...");
  ParseCommandLineFlags(&argc, &argv, true);

  rocksdb::RunBenchmark();
  return 0;
}

#endif  // GFLAGS
<|endoftext|>


<commit_before>/*!
 * \file painter_backend_gl_config.cpp
 * \brief file painter_backend_gl_config.cpp
 *
 * Copyright 2016 by Intel.
 *
 * Contact: kevin.rogovin@intel.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@intel.com>
 *
 */

#include "painter_backend_gl_config.hpp"

namespace fastuidraw { namespace gl { namespace detail {

bool
shader_storage_buffers_supported(const ContextProperties &ctx)
{
  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      return ctx.version() >= ivec2(3, 1);
    }
  #else
    {
      return ctx.version() >= ivec2(4, 3)
        || ctx.has_extension("GL_ARB_shader_storage_buffer_object");
    }
  #endif
}

enum glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_t
compute_provide_auxiliary_buffer(enum glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_t in_value,
                                 const ContextProperties &ctx)
{
  if (in_value == glsl::PainterShaderRegistrarGLSL::no_auxiliary_buffer)
    {
      return in_value;
    }

  /* If asking for auxiliary_buffer_framebuffer_fetch and have
   * the extension, immediately give the return value, otherwise
   * fall back to interlock. Note that we do NOT fallback
   * from interlock to framebuffer fetch because framebuffer-fetch
   * makes MSAA render targets become shaded per-sample.
   */
  if (in_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_framebuffer_fetch)
    {
      if (ctx.has_extension("GL_EXT_shader_framebuffer_fetch"))
        {
          return in_value;
        }
      else
        {
          in_value = glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock;
        }
    }

  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      if (ctx.version() <= ivec2(3, 0))
        {
          return glsl::PainterShaderRegistrarGLSL::no_auxiliary_buffer;
        }

      if (in_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic)
        {
          return in_value;
        }

      if (ctx.has_extension("GL_NV_fragment_shader_interlock")
          && ctx.has_extension("GL_NV_image_formats"))
        {
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only;
        }
      else
        {
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic;
        }
    }
  #else
    {
      bool have_interlock, have_interlock_main;

      if (ctx.version() <= ivec2(4, 1) && !ctx.has_extension("GL_ARB_shader_image_load_store"))
        {
          return glsl::PainterShaderRegistrarGLSL::no_auxiliary_buffer;
        }

      if (in_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic)
        {
          return in_value;
        }

      have_interlock = ctx.has_extension("GL_INTEL_fragment_shader_ordering");
      have_interlock_main = ctx.has_extension("GL_ARB_fragment_shader_interlock")
        || ctx.has_extension("GL_NV_fragment_shader_interlock");

      if (!have_interlock && !have_interlock_main)
        {
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic;
        }

      switch(in_value)
        {
        case glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only:
          return (have_interlock_main) ?
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only:
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock;

        case glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock:
          return (have_interlock) ?
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock:
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only;

        default:
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic;
        }
    }
  #endif
}

enum gl::detail::interlock_type_t
compute_interlock_type(const ContextProperties &ctx)
{
  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      if (ctx.has_extension("GL_NV_fragment_shader_interlock"))
        {
          return nv_fragment_shader_interlock;
        }
      else
        {
          return no_interlock;
        }
    }
  #else
    {
      if (ctx.has_extension("GL_INTEL_fragment_shader_ordering"))
        {
          return intel_fragment_shader_ordering;
        }
      else if (ctx.has_extension("GL_ARB_fragment_shader_interlock"))
        {
          return arb_fragment_shader_interlock;
        }
      else if (ctx.has_extension("GL_NV_fragment_shader_interlock"))
        {
          return nv_fragment_shader_interlock;
        }
      else
        {
          return no_interlock;
        }
    }
  #endif
}

enum glsl::PainterShaderRegistrarGLSL::compositing_type_t
compute_compositing_type(enum glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_t aux_value,
                      enum interlock_type_t interlock_value,
                      enum glsl::PainterShaderRegistrarGLSL::compositing_type_t in_value,
                      const ContextProperties &ctx)
{
  /*
   * First fallback to compositing_framebuffer_fetch if interlock is
   * requested but not availabe.
   */
  if (interlock_value == no_interlock
      && in_value == glsl::PainterShaderRegistrarGLSL::compositing_interlock)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch;
    }

  if (aux_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_framebuffer_fetch)
    {
      /*
       * auxiliary framebuffer fetch cannot be used with single and
       * dual source compositing; if it is single or dual source compositing
       * we will set it to framebuffer_fetch.
       */
      if (in_value == glsl::PainterShaderRegistrarGLSL::compositing_single_src
          || in_value == glsl::PainterShaderRegistrarGLSL::compositing_dual_src)
        {
          in_value = glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch;
        }
    }

  bool have_dual_src_compositing, have_framebuffer_fetch;
  if (ctx.is_es())
    {
      have_dual_src_compositing = ctx.has_extension("GL_EXT_composite_func_extended");
    }
  else
    {
      have_dual_src_compositing = true;
    }
  have_framebuffer_fetch = (aux_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_framebuffer_fetch)
    || ctx.has_extension("GL_EXT_shader_framebuffer_fetch");

  if (in_value == glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch
      && !have_framebuffer_fetch)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_interlock;
    }

  /* we do the test again against interlock because framebuffer
   * fetch code may have fallen back to interlock, but now
   * lacking interlock falls back to compositing_dual_src.
   */
  if (interlock_value == no_interlock
      && in_value == glsl::PainterShaderRegistrarGLSL::compositing_interlock)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_dual_src;
    }

  if (in_value == glsl::PainterShaderRegistrarGLSL::compositing_dual_src
      && !have_dual_src_compositing)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_single_src;
    }

  return in_value;
}

enum glsl::PainterShaderRegistrarGLSL::clipping_type_t
compute_clipping_type(enum glsl::PainterShaderRegistrarGLSL::compositing_type_t compositing_type,
                      enum glsl::PainterShaderRegistrarGLSL::clipping_type_t in_value,
                      const ContextProperties &ctx,
                      bool allow_gl_clip_distance)
{
  bool clip_distance_supported, skip_color_write_supported;
  skip_color_write_supported =
    compositing_type == glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch
    || compositing_type == glsl::PainterShaderRegistrarGLSL::compositing_interlock;

  if (in_value == glsl::PainterShaderRegistrarGLSL::clipping_via_discard)
    {
      return in_value;
    }

  if (in_value == glsl::PainterShaderRegistrarGLSL::clipping_via_skip_color_write)
    {
      if (skip_color_write_supported)
        {
          return in_value;
        }
      else
        {
          in_value = glsl::PainterShaderRegistrarGLSL::clipping_via_gl_clip_distance;
        }
    }

  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      if (allow_gl_clip_distance)
        {
          clip_distance_supported = ctx.has_extension("GL_EXT_clip_cull_distance")
            || ctx.has_extension("GL_APPLE_clip_distance");
        }
      else
        {
          clip_distance_supported = false;
        }
    }
  #else
    {
      FASTUIDRAWunused(ctx);
      clip_distance_supported = allow_gl_clip_distance;
    }
  #endif

  if (in_value == glsl::PainterShaderRegistrarGLSL::clipping_via_gl_clip_distance)
    {
      if (clip_distance_supported)
        {
          return in_value;
        }
      else if (skip_color_write_supported)
        {
          in_value = glsl::PainterShaderRegistrarGLSL::clipping_via_skip_color_write;
        }
      else
        {
          in_value = glsl::PainterShaderRegistrarGLSL::clipping_via_discard;
        }
    }

  return in_value;
}

}}}
<commit_msg>fastuidraw/gl_backend/private/painter_backend_gl_config:formatting fix<commit_after>/*!
 * \file painter_backend_gl_config.cpp
 * \brief file painter_backend_gl_config.cpp
 *
 * Copyright 2016 by Intel.
 *
 * Contact: kevin.rogovin@intel.com
 *
 * This Source Code Form is subject to the
 * terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with
 * this file, You can obtain one at
 * http://mozilla.org/MPL/2.0/.
 *
 * \author Kevin Rogovin <kevin.rogovin@intel.com>
 *
 */

#include "painter_backend_gl_config.hpp"

namespace fastuidraw { namespace gl { namespace detail {

bool
shader_storage_buffers_supported(const ContextProperties &ctx)
{
  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      return ctx.version() >= ivec2(3, 1);
    }
  #else
    {
      return ctx.version() >= ivec2(4, 3)
        || ctx.has_extension("GL_ARB_shader_storage_buffer_object");
    }
  #endif
}

enum glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_t
compute_provide_auxiliary_buffer(enum glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_t in_value,
                                 const ContextProperties &ctx)
{
  if (in_value == glsl::PainterShaderRegistrarGLSL::no_auxiliary_buffer)
    {
      return in_value;
    }

  /* If asking for auxiliary_buffer_framebuffer_fetch and have
   * the extension, immediately give the return value, otherwise
   * fall back to interlock. Note that we do NOT fallback
   * from interlock to framebuffer fetch because framebuffer-fetch
   * makes MSAA render targets become shaded per-sample.
   */
  if (in_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_framebuffer_fetch)
    {
      if (ctx.has_extension("GL_EXT_shader_framebuffer_fetch"))
        {
          return in_value;
        }
      else
        {
          in_value = glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock;
        }
    }

  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      if (ctx.version() <= ivec2(3, 0))
        {
          return glsl::PainterShaderRegistrarGLSL::no_auxiliary_buffer;
        }

      if (in_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic)
        {
          return in_value;
        }

      if (ctx.has_extension("GL_NV_fragment_shader_interlock")
          && ctx.has_extension("GL_NV_image_formats"))
        {
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only;
        }
      else
        {
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic;
        }
    }
  #else
    {
      bool have_interlock, have_interlock_main;

      if (ctx.version() <= ivec2(4, 1) && !ctx.has_extension("GL_ARB_shader_image_load_store"))
        {
          return glsl::PainterShaderRegistrarGLSL::no_auxiliary_buffer;
        }

      if (in_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic)
        {
          return in_value;
        }

      have_interlock = ctx.has_extension("GL_INTEL_fragment_shader_ordering");
      have_interlock_main = ctx.has_extension("GL_ARB_fragment_shader_interlock")
        || ctx.has_extension("GL_NV_fragment_shader_interlock");

      if (!have_interlock && !have_interlock_main)
        {
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic;
        }

      switch(in_value)
        {
        case glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only:
          return (have_interlock_main) ?
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only:
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock;

        case glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock:
          return (have_interlock) ?
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock:
            glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_interlock_main_only;

        default:
          return glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_atomic;
        }
    }
  #endif
}

enum gl::detail::interlock_type_t
compute_interlock_type(const ContextProperties &ctx)
{
  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      if (ctx.has_extension("GL_NV_fragment_shader_interlock"))
        {
          return nv_fragment_shader_interlock;
        }
      else
        {
          return no_interlock;
        }
    }
  #else
    {
      if (ctx.has_extension("GL_INTEL_fragment_shader_ordering"))
        {
          return intel_fragment_shader_ordering;
        }
      else if (ctx.has_extension("GL_ARB_fragment_shader_interlock"))
        {
          return arb_fragment_shader_interlock;
        }
      else if (ctx.has_extension("GL_NV_fragment_shader_interlock"))
        {
          return nv_fragment_shader_interlock;
        }
      else
        {
          return no_interlock;
        }
    }
  #endif
}

enum glsl::PainterShaderRegistrarGLSL::compositing_type_t
compute_compositing_type(enum glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_t aux_value,
                         enum interlock_type_t interlock_value,
                         enum glsl::PainterShaderRegistrarGLSL::compositing_type_t in_value,
                         const ContextProperties &ctx)
{
  /*
   * First fallback to compositing_framebuffer_fetch if interlock is
   * requested but not availabe.
   */
  if (interlock_value == no_interlock
      && in_value == glsl::PainterShaderRegistrarGLSL::compositing_interlock)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch;
    }

  if (aux_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_framebuffer_fetch)
    {
      /*
       * auxiliary framebuffer fetch cannot be used with single and
       * dual source compositing; if it is single or dual source compositing
       * we will set it to framebuffer_fetch.
       */
      if (in_value == glsl::PainterShaderRegistrarGLSL::compositing_single_src
          || in_value == glsl::PainterShaderRegistrarGLSL::compositing_dual_src)
        {
          in_value = glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch;
        }
    }

  bool have_dual_src_compositing, have_framebuffer_fetch;
  if (ctx.is_es())
    {
      have_dual_src_compositing = ctx.has_extension("GL_EXT_composite_func_extended");
    }
  else
    {
      have_dual_src_compositing = true;
    }
  have_framebuffer_fetch = (aux_value == glsl::PainterShaderRegistrarGLSL::auxiliary_buffer_framebuffer_fetch)
    || ctx.has_extension("GL_EXT_shader_framebuffer_fetch");

  if (in_value == glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch
      && !have_framebuffer_fetch)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_interlock;
    }

  /* we do the test again against interlock because framebuffer
   * fetch code may have fallen back to interlock, but now
   * lacking interlock falls back to compositing_dual_src.
   */
  if (interlock_value == no_interlock
      && in_value == glsl::PainterShaderRegistrarGLSL::compositing_interlock)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_dual_src;
    }

  if (in_value == glsl::PainterShaderRegistrarGLSL::compositing_dual_src
      && !have_dual_src_compositing)
    {
      in_value = glsl::PainterShaderRegistrarGLSL::compositing_single_src;
    }

  return in_value;
}

enum glsl::PainterShaderRegistrarGLSL::clipping_type_t
compute_clipping_type(enum glsl::PainterShaderRegistrarGLSL::compositing_type_t compositing_type,
                      enum glsl::PainterShaderRegistrarGLSL::clipping_type_t in_value,
                      const ContextProperties &ctx,
                      bool allow_gl_clip_distance)
{
  bool clip_distance_supported, skip_color_write_supported;
  skip_color_write_supported =
    compositing_type == glsl::PainterShaderRegistrarGLSL::compositing_framebuffer_fetch
    || compositing_type == glsl::PainterShaderRegistrarGLSL::compositing_interlock;

  if (in_value == glsl::PainterShaderRegistrarGLSL::clipping_via_discard)
    {
      return in_value;
    }

  if (in_value == glsl::PainterShaderRegistrarGLSL::clipping_via_skip_color_write)
    {
      if (skip_color_write_supported)
        {
          return in_value;
        }
      else
        {
          in_value = glsl::PainterShaderRegistrarGLSL::clipping_via_gl_clip_distance;
        }
    }

  #ifdef FASTUIDRAW_GL_USE_GLES
    {
      if (allow_gl_clip_distance)
        {
          clip_distance_supported = ctx.has_extension("GL_EXT_clip_cull_distance")
            || ctx.has_extension("GL_APPLE_clip_distance");
        }
      else
        {
          clip_distance_supported = false;
        }
    }
  #else
    {
      FASTUIDRAWunused(ctx);
      clip_distance_supported = allow_gl_clip_distance;
    }
  #endif

  if (in_value == glsl::PainterShaderRegistrarGLSL::clipping_via_gl_clip_distance)
    {
      if (clip_distance_supported)
        {
          return in_value;
        }
      else if (skip_color_write_supported)
        {
          in_value = glsl::PainterShaderRegistrarGLSL::clipping_via_skip_color_write;
        }
      else
        {
          in_value = glsl::PainterShaderRegistrarGLSL::clipping_via_discard;
        }
    }

  return in_value;
}

}}}
<|endoftext|>