<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cstring>
#include "core/CompileConfig.h"
#include "Texture.h"
#include "core/Engine.h"
#include "Renderer.h"
#include "Image.h"
#include "utils/Utils.h"
#include "math/MathUtils.h"

namespace ouzel
{
    namespace graphics
    {
        Texture::Texture()
        {

        }

        Texture::~Texture()
        {

        }

        void Texture::free()
        {
            levels.clear();
            uploadData.levels.clear();

            ready = false;
        }

        bool Texture::init(const Size2& newSize, bool newDynamic, bool newMipmaps, bool newRenderTarget)
        {
            free();

            size = newSize;
            dynamic = newDynamic;
            mipmaps = newMipmaps;
            renderTarget = newRenderTarget;

            dirty = true;

            sharedEngine->getRenderer()->scheduleUpdate(shared_from_this());

            return true;
        }

        bool Texture::initFromFile(const std::string& newFilename, bool newDynamic, bool newMipmaps)
        {
            free();

            filename = newFilename;

            Image image;
            if (!image.initFromFile(filename))
            {
                return false;
            }

            return initFromBuffer(image.getData(), image.getSize(), newDynamic, newMipmaps);
        }

        bool Texture::initFromBuffer(const std::vector<uint8_t>& newData, const Size2& newSize, bool newDynamic, bool newMipmaps)
        {
            free();

            dynamic = newDynamic;
            mipmaps = newMipmaps;
            renderTarget = false;

            dirty = true;

            if (!calculateData(newData, newSize))
            {
                return false;
            }

            sharedEngine->getRenderer()->scheduleUpdate(shared_from_this());

            return true;
        }

        static void imageRgba8Downsample2x2(uint32_t width, uint32_t height, uint32_t pitch, const uint8_t* src, uint8_t* dst)
        {
            const uint32_t dstwidth  = width / 2;
            const uint32_t dstheight = height / 2;

            if (dstwidth == 0 ||  dstheight == 0)
            {
                return;
            }

            for (uint32_t y = 0, ystep = pitch * 2; y < dstheight; ++y, src += ystep)
            {
                const uint8_t* rgba = src;
                for (uint32_t x = 0; x < dstwidth; ++x, rgba += 8, dst += 4)
                {
                    float pixels = 0.0f;

                    float r = 0, g = 0, b = 0, a = 0;

                    if (rgba[3] > 0)
                    {
                        r += powf(rgba[0], 2.2f);
                        g += powf(rgba[1], 2.2f);
                        b += powf(rgba[2], 2.2f);
                        pixels += 1.0f;
                    }
                    a = rgba[3];

                    if (rgba[7] > 0)
                    {
                        r += powf(rgba[4], 2.2f);
                        g += powf(rgba[5], 2.2f);
                        b += powf(rgba[6], 2.2f);
                        pixels += 1.0f;
                    }
                    a += rgba[7];

                    if (rgba[pitch+3])
                    {
                        r += powf(rgba[pitch+0], 2.2f);
                        g += powf(rgba[pitch+1], 2.2f);
                        b += powf(rgba[pitch+2], 2.2f);
                        pixels += 1.0f;
                    }
                    a += rgba[pitch+3];

                    if (rgba[pitch+7] > 0)
                    {
                        r += powf(rgba[pitch+4], 2.2f);
                        g += powf(rgba[pitch+5], 2.2f);
                        b += powf(rgba[pitch+6], 2.2f);
                        pixels += 1.0f;
                    }
                    a += rgba[pitch+7];

                    if (pixels > 0.0f)
                    {
                        r /= pixels;
                        g /= pixels;
                        b /= pixels;
                    }
                    else
                    {
                        r = g = b = 0;
                    }

                    a *= 0.25f;
                    r = powf(r, 1.0f / 2.2f);
                    g = powf(g, 1.0f / 2.2f);
                    b = powf(b, 1.0f / 2.2f);
                    dst[0] = (uint8_t)r;
                    dst[1] = (uint8_t)g;
                    dst[2] = (uint8_t)b;
                    dst[3] = (uint8_t)a;
                }
            }
        }

        bool Texture::setData(const std::vector<uint8_t>& newData, const Size2& newSize)
        {
            if (!dynamic)
            {
                return false;
            }

            if (newSize.width <= 0.0f || newSize.height <= 0.0f)
            {
                return false;
            }

            return calculateData(newData, newSize);
        }

        bool Texture::calculateData(const std::vector<uint8_t>& newData, const Size2& newSize)
        {
            levels.clear();
            size = newSize;

            levels.push_back({ newSize, newData });

            uint32_t newWidth = static_cast<uint32_t>(newSize.width);
            uint32_t newHeight = static_cast<uint32_t>(newSize.height);

#if OUZEL_SUPPORTS_OPENGLES
            if (mipmaps && (sharedEngine->getRenderer()->getDriver() != Renderer::Driver::OPENGL || (isPOT(newWidth) && isPOT(newHeight))))
#else
            if (mipmaps)
#endif
            {
                uint32_t pitch = newWidth * 4;

                uint32_t bufferSize = newWidth * newHeight * 4;

                if (newWidth == 1)
                {
                    bufferSize *= 2;
                }
                if (newHeight == 1)
                {
                    bufferSize *= 2;
                }

                std::vector<uint8_t> mipMapData(bufferSize);
                memcpy(mipMapData.data(), newData.data(), newWidth * newHeight * 4);

                while (newWidth >= 2 && newHeight >= 2)
                {
                    imageRgba8Downsample2x2(newWidth, newHeight, pitch, mipMapData.data(), mipMapData.data());

                    newWidth >>= 1;
                    newHeight >>= 1;

                    Size2 mipMapSize = Size2(static_cast<float>(newWidth), static_cast<float>(newHeight));
                    levels.push_back({ mipMapSize, mipMapData });

                    pitch = newWidth * 4;
                }

                if (newWidth > newHeight)
                {
                    for (; newWidth >= 2;)
                    {
                        memcpy(&mipMapData.data()[newWidth*4], mipMapData.data(), newWidth * 4);

                        imageRgba8Downsample2x2(newWidth, 2, pitch, mipMapData.data(), mipMapData.data());

                        newWidth >>= 1;

                        Size2 mipMapSize = Size2(static_cast<float>(newWidth), static_cast<float>(newHeight));
                        levels.push_back({ mipMapSize, mipMapData });

                        pitch = newWidth * 4;
                    }
                }
                else
                {
                    for (; newHeight >= 2;)
                    {
                        uint32_t* src = reinterpret_cast<uint32_t*>(mipMapData.data());
                        for (int32_t i = static_cast<int32_t>(newHeight) - 1; i >= 0; --i)
                        {
                            src[i * 2] = src[i];
                            src[i * 2 + 1] = src[i];
                        }

                        imageRgba8Downsample2x2(2, newHeight, 8, mipMapData.data(), mipMapData.data());

                        newHeight >>= 1;

                        Size2 mipMapSize = Size2(static_cast<float>(newWidth), static_cast<float>(newHeight));
                        levels.push_back({ mipMapSize, mipMapData });
                    }
                }
            }

            sharedEngine->getRenderer()->scheduleUpdate(shared_from_this());

            return true;
        }

        bool Texture::update()
        {
            uploadData.size = size;
            uploadData.dynamic = dynamic;
            uploadData.mipmaps = mipmaps;
            uploadData.renderTarget = renderTarget;

            if (!levels.empty())
            {
                uploadData.levels = std::move(levels);
            }

            return true;
        }
    } // namespace graphics
} // namespace ouzel
<commit_msg>Improve texture upload code<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <cstring>
#include "core/CompileConfig.h"
#include "Texture.h"
#include "core/Engine.h"
#include "Renderer.h"
#include "Image.h"
#include "utils/Utils.h"
#include "math/MathUtils.h"

namespace ouzel
{
    namespace graphics
    {
        Texture::Texture()
        {

        }

        Texture::~Texture()
        {

        }

        void Texture::free()
        {
            levels.clear();
            uploadData.levels.clear();

            ready = false;
        }

        bool Texture::init(const Size2& newSize, bool newDynamic, bool newMipmaps, bool newRenderTarget)
        {
            free();

            size = newSize;
            dynamic = newDynamic;
            mipmaps = newMipmaps;
            renderTarget = newRenderTarget;

            dirty = true;

            sharedEngine->getRenderer()->scheduleUpdate(shared_from_this());

            return true;
        }

        bool Texture::initFromFile(const std::string& newFilename, bool newDynamic, bool newMipmaps)
        {
            free();

            filename = newFilename;

            Image image;
            if (!image.initFromFile(filename))
            {
                return false;
            }

            return initFromBuffer(image.getData(), image.getSize(), newDynamic, newMipmaps);
        }

        bool Texture::initFromBuffer(const std::vector<uint8_t>& newData, const Size2& newSize, bool newDynamic, bool newMipmaps)
        {
            free();

            dynamic = newDynamic;
            mipmaps = newMipmaps;
            renderTarget = false;

            if (!calculateData(newData, newSize))
            {
                return false;
            }

            dirty = true;

            sharedEngine->getRenderer()->scheduleUpdate(shared_from_this());

            return true;
        }

        bool Texture::setData(const std::vector<uint8_t>& newData, const Size2& newSize)
        {
            if (!dynamic)
            {
                return false;
            }

            if (newSize.width <= 0.0f || newSize.height <= 0.0f)
            {
                return false;
            }

            if (!calculateData(newData, newSize))
            {
                return false;
            }

            dirty = true;

            sharedEngine->getRenderer()->scheduleUpdate(shared_from_this());

            return true;
        }

        static void imageRgba8Downsample2x2(uint32_t width, uint32_t height, uint32_t pitch, const uint8_t* src, uint8_t* dst)
        {
            const uint32_t dstwidth  = width / 2;
            const uint32_t dstheight = height / 2;

            if (dstwidth == 0 ||  dstheight == 0)
            {
                return;
            }

            for (uint32_t y = 0, ystep = pitch * 2; y < dstheight; ++y, src += ystep)
            {
                const uint8_t* rgba = src;
                for (uint32_t x = 0; x < dstwidth; ++x, rgba += 8, dst += 4)
                {
                    float pixels = 0.0f;

                    float r = 0, g = 0, b = 0, a = 0;

                    if (rgba[3] > 0)
                    {
                        r += powf(rgba[0], 2.2f);
                        g += powf(rgba[1], 2.2f);
                        b += powf(rgba[2], 2.2f);
                        pixels += 1.0f;
                    }
                    a = rgba[3];

                    if (rgba[7] > 0)
                    {
                        r += powf(rgba[4], 2.2f);
                        g += powf(rgba[5], 2.2f);
                        b += powf(rgba[6], 2.2f);
                        pixels += 1.0f;
                    }
                    a += rgba[7];

                    if (rgba[pitch+3])
                    {
                        r += powf(rgba[pitch+0], 2.2f);
                        g += powf(rgba[pitch+1], 2.2f);
                        b += powf(rgba[pitch+2], 2.2f);
                        pixels += 1.0f;
                    }
                    a += rgba[pitch+3];

                    if (rgba[pitch+7] > 0)
                    {
                        r += powf(rgba[pitch+4], 2.2f);
                        g += powf(rgba[pitch+5], 2.2f);
                        b += powf(rgba[pitch+6], 2.2f);
                        pixels += 1.0f;
                    }
                    a += rgba[pitch+7];

                    if (pixels > 0.0f)
                    {
                        r /= pixels;
                        g /= pixels;
                        b /= pixels;
                    }
                    else
                    {
                        r = g = b = 0;
                    }

                    a *= 0.25f;
                    r = powf(r, 1.0f / 2.2f);
                    g = powf(g, 1.0f / 2.2f);
                    b = powf(b, 1.0f / 2.2f);
                    dst[0] = (uint8_t)r;
                    dst[1] = (uint8_t)g;
                    dst[2] = (uint8_t)b;
                    dst[3] = (uint8_t)a;
                }
            }
        }

        bool Texture::calculateData(const std::vector<uint8_t>& newData, const Size2& newSize)
        {
            levels.clear();
            size = newSize;

            levels.push_back({ newSize, newData });

            uint32_t newWidth = static_cast<uint32_t>(newSize.width);
            uint32_t newHeight = static_cast<uint32_t>(newSize.height);

#if OUZEL_SUPPORTS_OPENGLES
            if (mipmaps && (sharedEngine->getRenderer()->getDriver() != Renderer::Driver::OPENGL || (isPOT(newWidth) && isPOT(newHeight))))
#else
            if (mipmaps)
#endif
            {
                uint32_t pitch = newWidth * 4;

                uint32_t bufferSize = newWidth * newHeight * 4;

                if (newWidth == 1)
                {
                    bufferSize *= 2;
                }
                if (newHeight == 1)
                {
                    bufferSize *= 2;
                }

                std::vector<uint8_t> mipMapData(bufferSize);
                memcpy(mipMapData.data(), newData.data(), newWidth * newHeight * 4);

                while (newWidth >= 2 && newHeight >= 2)
                {
                    imageRgba8Downsample2x2(newWidth, newHeight, pitch, mipMapData.data(), mipMapData.data());

                    newWidth >>= 1;
                    newHeight >>= 1;

                    Size2 mipMapSize = Size2(static_cast<float>(newWidth), static_cast<float>(newHeight));
                    levels.push_back({ mipMapSize, mipMapData });

                    pitch = newWidth * 4;
                }

                if (newWidth > newHeight)
                {
                    for (; newWidth >= 2;)
                    {
                        memcpy(&mipMapData.data()[newWidth*4], mipMapData.data(), newWidth * 4);

                        imageRgba8Downsample2x2(newWidth, 2, pitch, mipMapData.data(), mipMapData.data());

                        newWidth >>= 1;

                        Size2 mipMapSize = Size2(static_cast<float>(newWidth), static_cast<float>(newHeight));
                        levels.push_back({ mipMapSize, mipMapData });

                        pitch = newWidth * 4;
                    }
                }
                else
                {
                    for (; newHeight >= 2;)
                    {
                        uint32_t* src = reinterpret_cast<uint32_t*>(mipMapData.data());
                        for (int32_t i = static_cast<int32_t>(newHeight) - 1; i >= 0; --i)
                        {
                            src[i * 2] = src[i];
                            src[i * 2 + 1] = src[i];
                        }

                        imageRgba8Downsample2x2(2, newHeight, 8, mipMapData.data(), mipMapData.data());

                        newHeight >>= 1;

                        Size2 mipMapSize = Size2(static_cast<float>(newWidth), static_cast<float>(newHeight));
                        levels.push_back({ mipMapSize, mipMapData });
                    }
                }
            }

            return true;
        }

        bool Texture::update()
        {
            uploadData.size = size;
            uploadData.dynamic = dynamic;
            uploadData.mipmaps = mipmaps;
            uploadData.renderTarget = renderTarget;

            if (!levels.empty())
            {
                uploadData.levels = std::move(levels);
            }

            return true;
        }
    } // namespace graphics
} // namespace ouzel
<|endoftext|>


<commit_before><commit_msg>Convert SV_DECL_PTRARR to std::vector<commit_after><|endoftext|>


<commit_before>//------------------------------------------------------------------------------
//  DrawCallExplorer.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/App.h"
#include "Gfx/Gfx.h"
#include "Assets/Gfx/ShapeBuilder.h"
#include "Input/Input.h"
#include "Time/Clock.h"
#include "IMUI/IMUI.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/random.hpp"
#include "shaders.h"

using namespace Oryol;

class DrawCallExplorerApp : public App {
public:
    AppState::Code OnRunning();
    AppState::Code OnInit();
    AppState::Code OnCleanup();

private:
    void updateCamera();
    void emitParticles();
    void updateParticles();
    void drawUI();

    int maxNumParticles = 10000;
    int numEmitParticles = 100;
    int curNumParticles = 0;
    int numParticlesPerBatch = 1000;

    StaticArray<Id,3> drawStates;

    glm::mat4 view;
    glm::mat4 proj;
    glm::mat4 model;

    // FIXME: hmm these param blocks are actually compatibel across shaders
    Shaders::Red::PerFrameParams perFrameParams;
    Shaders::Red::PerParticleParams perParticleParams;

    static const int ParticleBufferSize = 1000000;
    bool updateEnabled = true;
    int32 frameCount = 0;
    TimePoint lastFrameTimePoint;
    struct {
        glm::vec4 pos;
        glm::vec4 vec;
    } particles[ParticleBufferSize];
};
OryolMain(DrawCallExplorerApp);

//------------------------------------------------------------------------------
AppState::Code
DrawCallExplorerApp::OnRunning() {

    Duration updTime, drawTime, applyRtTime;
    this->frameCount++;

    // update block
    this->updateCamera();
    if (this->updateEnabled) {
        TimePoint updStart = Clock::Now();
        this->emitParticles();
        this->updateParticles();
        updTime = Clock::Since(updStart);
    }

    // render block
    TimePoint applyRtStart = Clock::Now();
    Gfx::ApplyDefaultRenderTarget(ClearState::ClearAll(glm::vec4(0.5f, 0.5f, 0.5f, 1.0f), 1.0f, 0));
    applyRtTime = Clock::Since(applyRtStart);
    TimePoint drawStart = Clock::Now();
    int batchCount = this->numParticlesPerBatch;
    int curBatch = 0;
    for (int32 i = 0; i < this->curNumParticles; i++) {
        if (++batchCount > this->numParticlesPerBatch) {
            batchCount = 0;
            Gfx::ApplyDrawState(this->drawStates[curBatch++]);
            Gfx::ApplyUniformBlock(this->perFrameParams);
            if (curBatch >= 3) {
                curBatch = 0;
            }
        }
        this->perParticleParams.Translate = this->particles[i].pos;
        Gfx::ApplyUniformBlock(this->perParticleParams);
        Gfx::Draw(0);
    }
    drawTime = Clock::Since(drawStart);

    this->drawUI();
    Gfx::CommitFrame();

    return Gfx::QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::updateCamera() {
    float32 angle = this->frameCount * 0.01f;
    glm::vec3 pos(glm::sin(angle) * 10.0f, 2.5f, glm::cos(angle) * 10.0f);
    this->view = glm::lookAt(pos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->perFrameParams.ModelViewProjection = this->proj * this->view * this->model;
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::emitParticles() {
    for (int32 i = 0;
        (this->curNumParticles < this->maxNumParticles) &&
        (i < this->numEmitParticles);
        i++) {

        this->particles[this->curNumParticles].pos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
        glm::vec3 rnd = glm::ballRand(0.5f);
        rnd.y += 2.0f;
        this->particles[this->curNumParticles].vec = glm::vec4(rnd, 0.0f);
        this->curNumParticles++;
    }
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::updateParticles() {
    const float32 frameTime = 1.0f / 60.0f;
    for (int32 i = 0; i < this->curNumParticles; i++) {
        auto& curParticle = this->particles[i];
        curParticle.vec.y -= 1.0f * frameTime;
        curParticle.pos += curParticle.vec * frameTime;
        if (curParticle.pos.y < -2.0f) {
            curParticle.pos.y = -1.8f;
            curParticle.vec.y = -curParticle.vec.y;
            curParticle.vec *= 0.8f;
        }
    }
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallExplorerApp::OnInit() {
    // setup rendering system
    GfxSetup gfxSetup = GfxSetup::Window(800, 500, "Oryol DrawCallPerf Sample");
    gfxSetup.GlobalUniformBufferSize = 1024 * 1024 * 32;
    Gfx::Setup(gfxSetup);
    Input::Setup();
    Input::BeginCaptureText();
    IMUI::Setup();

    // create resources
    const glm::mat4 rot90 = glm::rotate(glm::mat4(), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    ShapeBuilder shapeBuilder;
    shapeBuilder.RandomColors = true;
    shapeBuilder.Layout
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Color0, VertexFormat::Float4);
    shapeBuilder.Transform(rot90).Sphere(0.05f, 3, 2);
    Id mesh = Gfx::CreateResource(shapeBuilder.Build());

    Id redShd   = Gfx::CreateResource(Shaders::Red::Setup());
    Id greenShd = Gfx::CreateResource(Shaders::Green::Setup());
    Id blueShd  = Gfx::CreateResource(Shaders::Blue::Setup());

    auto dss = DrawStateSetup::FromMeshAndShader(mesh, redShd);
    dss.RasterizerState.CullFaceEnabled = true;
    dss.DepthStencilState.DepthWriteEnabled = true;
    dss.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    this->drawStates[0] = Gfx::CreateResource(dss);
    dss.Shader = greenShd;
    this->drawStates[1] = Gfx::CreateResource(dss);
    dss.Shader = blueShd;
    this->drawStates[2] = Gfx::CreateResource(dss);

    // setup projection and view matrices
    const float32 fbWidth = (const float32) Gfx::DisplayAttrs().FramebufferWidth;
    const float32 fbHeight = (const float32) Gfx::DisplayAttrs().FramebufferHeight;
    this->proj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::lookAt(glm::vec3(0.0f, 2.5f, 0.0f), glm::vec3(0.0f, 0.0f, -10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->model = glm::mat4();

    return App::OnInit();
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallExplorerApp::OnCleanup() {
    IMUI::Discard();
    Input::Discard();
    Gfx::Discard();
    return App::OnCleanup();
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::drawUI() {
    IMUI::NewFrame();
    ImGui::SetNextWindowSize(ImVec2(240, 200), ImGuiSetCond_Once);
    if (ImGui::Begin("Controls")) {
        if (ImGui::Button("Reset")) {
            this->curNumParticles = 0;
        }
        ImGui::PushItemWidth(100.0f);
        if (ImGui::InputInt("Max Particles", &this->maxNumParticles, 100, 1000, ImGuiInputTextFlags_EnterReturnsTrue)) {
            if (this->maxNumParticles > ParticleBufferSize) {
                this->maxNumParticles = ParticleBufferSize;
            }
            this->curNumParticles = 0;
        }
        if (ImGui::InputInt("Batch Size", &this->numParticlesPerBatch, 10, 100, ImGuiInputTextFlags_EnterReturnsTrue)) {
            this->curNumParticles = 0;
        }
        ImGui::InputInt("Emit Per Frame", &this->numEmitParticles, 1, 10, ImGuiInputTextFlags_EnterReturnsTrue);
        ImGui::PopItemWidth();
    }
    ImGui::End();
    ImGui::Render();

}
<commit_msg>More DrawCallExplorer stuff<commit_after>//------------------------------------------------------------------------------
//  DrawCallExplorer.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/App.h"
#include "Gfx/Gfx.h"
#include "Assets/Gfx/ShapeBuilder.h"
#include "Input/Input.h"
#include "Time/Clock.h"
#include "IMUI/IMUI.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/random.hpp"
#include "shaders.h"

using namespace Oryol;

class DrawCallExplorerApp : public App {
public:
    AppState::Code OnRunning();
    AppState::Code OnInit();
    AppState::Code OnCleanup();

private:
    void updateCamera();
    void emitParticles();
    void updateParticles();
    void drawUI();
    void reset();

    int maxNumParticles = 10000;
    int numEmitParticles = 100;
    int curNumParticles = 0;
    int numParticlesPerBatch = 1000;

    StaticArray<Id,3> drawStates;

    glm::mat4 view;
    glm::mat4 proj;
    glm::mat4 model;

    // FIXME: hmm these param blocks are actually compatibel across shaders
    Shaders::Red::PerFrameParams perFrameParams;
    Shaders::Red::PerParticleParams perParticleParams;

    static const int ParticleBufferSize = 1000000;
    bool updateEnabled = true;
    int32 frameCount = 0;
    TimePoint lastFrameTimePoint;
    struct {
        glm::vec4 pos;
        glm::vec4 vec;
    } particles[ParticleBufferSize];

    int32 numApplyDrawState = 0;
    int32 numDrawCalls = 0;

    // NumSamples must be 2^N, all samples are 0.0 to 1.0 (0..32ms)
    static const int NumSamples = 1024;
    uint32 curSample = 0;
    struct sample {
        float updTime = 0.0f;
        float applyRtTime = 0.0f;
        float drawTime = 0.0f;
        float frameTime = 0.0f;
    };
    sample samples[NumSamples];
};
OryolMain(DrawCallExplorerApp);

//------------------------------------------------------------------------------
AppState::Code
DrawCallExplorerApp::OnRunning() {

    TimePoint start, afterUpdate, afterApplyRt, afterDraw;
    this->frameCount++;
    this->numDrawCalls = 0;
    this->numApplyDrawState = 0;

    // update block
    start = Clock::Now();
    this->updateCamera();
    if (this->updateEnabled) {
        this->emitParticles();
        this->updateParticles();
    }
    afterUpdate = Clock::Now();

    // render block
    Gfx::ApplyDefaultRenderTarget(ClearState::ClearAll(glm::vec4(0.5f, 0.5f, 0.5f, 1.0f), 1.0f, 0));
    afterApplyRt = Clock::Now();
    int batchCount = this->numParticlesPerBatch;
    int curBatch = 0;
    for (int32 i = 0; i < this->curNumParticles; i++) {
        if (++batchCount >= this->numParticlesPerBatch) {
            batchCount = 0;
            Gfx::ApplyDrawState(this->drawStates[curBatch++]);
            Gfx::ApplyUniformBlock(this->perFrameParams);
            if (curBatch >= 3) {
                curBatch = 0;
            }
            this->numApplyDrawState++;
        }
        this->perParticleParams.Translate = this->particles[i].pos;
        Gfx::ApplyUniformBlock(this->perParticleParams);
        Gfx::Draw(0);
        this->numDrawCalls++;
    }
    afterDraw = Clock::Now();

    this->drawUI();
    Gfx::CommitFrame();

    // record time samples
    auto& s = this->samples[this->curSample++ & (NumSamples-1)];
    s.updTime = (afterUpdate - start).AsMilliSeconds();
    s.applyRtTime = (afterApplyRt - afterUpdate).AsMilliSeconds();
    s.drawTime = (afterDraw - afterApplyRt).AsMilliSeconds();
    s.frameTime = Clock::LapTime(this->lastFrameTimePoint).AsMilliSeconds();

    return Gfx::QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::updateCamera() {
    float32 angle = this->frameCount * 0.01f;
    glm::vec3 pos(glm::sin(angle) * 10.0f, 2.5f, glm::cos(angle) * 10.0f);
    this->view = glm::lookAt(pos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->perFrameParams.ModelViewProjection = this->proj * this->view * this->model;
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::emitParticles() {
    for (int32 i = 0;
        (this->curNumParticles < this->maxNumParticles) &&
        (i < this->numEmitParticles);
        i++) {

        this->particles[this->curNumParticles].pos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
        glm::vec3 rnd = glm::ballRand(0.5f);
        rnd.y += 2.0f;
        this->particles[this->curNumParticles].vec = glm::vec4(rnd, 0.0f);
        this->curNumParticles++;
    }
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::updateParticles() {
    const float32 frameTime = 1.0f / 60.0f;
    for (int32 i = 0; i < this->curNumParticles; i++) {
        auto& curParticle = this->particles[i];
        curParticle.vec.y -= 1.0f * frameTime;
        curParticle.pos += curParticle.vec * frameTime;
        if (curParticle.pos.y < -2.0f) {
            curParticle.pos.y = -1.8f;
            curParticle.vec.y = -curParticle.vec.y;
            curParticle.vec *= 0.8f;
        }
    }
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::reset() {
    this->curNumParticles = 0;
    this->curSample = 0;
    for (auto& s : this->samples) {
        s = sample();
    }
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallExplorerApp::OnInit() {
    // setup rendering system
    GfxSetup gfxSetup = GfxSetup::Window(800, 500, "Oryol DrawCallPerf Sample");
    gfxSetup.GlobalUniformBufferSize = 1024 * 1024 * 32;
    Gfx::Setup(gfxSetup);
    Input::Setup();
    Input::BeginCaptureText();
    IMUI::Setup();

    // create resources
    const glm::mat4 rot90 = glm::rotate(glm::mat4(), glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    ShapeBuilder shapeBuilder;
    shapeBuilder.RandomColors = true;
    shapeBuilder.Layout
        .Add(VertexAttr::Position, VertexFormat::Float3)
        .Add(VertexAttr::Color0, VertexFormat::Float4);
    shapeBuilder.Transform(rot90).Sphere(0.05f, 3, 2);
    Id mesh = Gfx::CreateResource(shapeBuilder.Build());

    Id redShd   = Gfx::CreateResource(Shaders::Red::Setup());
    Id greenShd = Gfx::CreateResource(Shaders::Green::Setup());
    Id blueShd  = Gfx::CreateResource(Shaders::Blue::Setup());

    auto dss = DrawStateSetup::FromMeshAndShader(mesh, redShd);
    dss.RasterizerState.CullFaceEnabled = true;
    dss.DepthStencilState.DepthWriteEnabled = true;
    dss.DepthStencilState.DepthCmpFunc = CompareFunc::LessEqual;
    this->drawStates[0] = Gfx::CreateResource(dss);
    dss.Shader = greenShd;
    this->drawStates[1] = Gfx::CreateResource(dss);
    dss.Shader = blueShd;
    this->drawStates[2] = Gfx::CreateResource(dss);

    // setup projection and view matrices
    const float32 fbWidth = (const float32) Gfx::DisplayAttrs().FramebufferWidth;
    const float32 fbHeight = (const float32) Gfx::DisplayAttrs().FramebufferHeight;
    this->proj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::lookAt(glm::vec3(0.0f, 2.5f, 0.0f), glm::vec3(0.0f, 0.0f, -10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->model = glm::mat4();

    this->lastFrameTimePoint = Clock::Now();

    return App::OnInit();
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallExplorerApp::OnCleanup() {
    IMUI::Discard();
    Input::Discard();
    Gfx::Discard();
    return App::OnCleanup();
}

//------------------------------------------------------------------------------
void
DrawCallExplorerApp::drawUI() {
    IMUI::NewFrame();
    ImGui::SetNextWindowSize(ImVec2(240, 200), ImGuiSetCond_Once);
    if (ImGui::Begin("Controls")) {
        if (ImGui::Button("Reset")) {
            this->reset();
        }
        ImGui::PushItemWidth(100.0f);
        if (ImGui::InputInt("Max Particles", &this->maxNumParticles, 1000, 10000, ImGuiInputTextFlags_EnterReturnsTrue)) {
            if (this->maxNumParticles > ParticleBufferSize) {
                this->maxNumParticles = ParticleBufferSize;
            }
            this->reset();
        }
        if (ImGui::InputInt("Batch Size", &this->numParticlesPerBatch, 100, 1000, ImGuiInputTextFlags_EnterReturnsTrue)) {
            this->reset();
        }
        if (ImGui::InputInt("Emit Per Frame", &this->numEmitParticles, 10, 100, ImGuiInputTextFlags_EnterReturnsTrue)) {
            this->reset();
        }
        ImGui::Text("Num ApplyDrawState: %d", this->numApplyDrawState);
        ImGui::Text("Num DrawCalls:      %d", this->numDrawCalls);
        ImGui::PopItemWidth();
    }
    ImGui::End();
    ImGui::SetNextWindowPos(ImVec2(10, 320), ImGuiSetCond_Once);
    ImGui::SetNextWindowSize(ImVec2(700, 180), ImGuiSetCond_Once);
    if (ImGui::Begin("Timing")) {
        const auto& s0 = this->samples[0];
        const auto& s1 = this->samples[(this->curSample-1) & (NumSamples-1)];
        ImGui::PlotLines("##upd", &s0.updTime, NumSamples, 0, nullptr, 0.0f, 32.0f, ImVec2(0, 32), sizeof(sample));
        ImGui::SameLine(); ImGui::Text("update:  %.3fms", s1.updTime);
        ImGui::PlotLines("##applyRt", &s0.applyRtTime, NumSamples, 0, nullptr, 0.0f, 32.0f, ImVec2(0, 32), sizeof(sample));
        ImGui::SameLine(); ImGui::Text("applyRt: %.3fms", s1.applyRtTime);
        ImGui::PlotLines("##draw", &s0.drawTime, NumSamples, 0, nullptr, 0.0f, 32.0f, ImVec2(0, 32), sizeof(sample));
        ImGui::SameLine(); ImGui::Text("draw:    %.3fms", s1.drawTime);
        ImGui::PlotLines("##frame", &s0.frameTime, NumSamples, 0, nullptr, 0.0f, 32.0f, ImVec2(0, 32), sizeof(sample));
        ImGui::SameLine(); ImGui::Text("frame:   %.3fms", s1.frameTime);
    }
    ImGui::End();
    ImGui::Render();
}
<|endoftext|>


<commit_before>#include "context.hpp"
#include "expr.hpp"
#include "action.hpp"

namespace pip
{
  context::context(cc::diagnostic_manager& diags,
                   cc::input_manager& in,
                   cc::symbol_table& syms)
    : diags(diags), input(in), syms(syms)
  { }

  symbol*
  context::get_symbol(const char* str)
  {
    return syms.get(str);
  }

  symbol*
  context::get_symbol(const std::string& str)
  {
    return syms.get(str);
  }

	expr*
	context::make_int_expr(type* t, int val)
	{
		return new int_expr(t, val);
	}

	expr*
	context::make_range_expr(type* t, int lo, int hi)
	{
		return new range_expr(t, lo, hi);
	}

	expr*
	context::make_wild_expr(type* t, int val, int mask)
	{
		return new wild_expr(t, val, mask);
	}

	expr*
	context::make_miss_expr(type* t)
	{
		return new miss_expr(t);
	}

	expr*
	context::make_ref_expr(type* t, symbol* id)
	{
		return new ref_expr(t, id);
	}

	expr*
	context::make_field_expr(type* t, expr_kind kind)
	{
		return new field_expr(kind, t);
	}

	action*
	context::make_action(action_kind k)
	{
		return new action(k);
	}

} // namesapce pip
<commit_msg>make_action now returns derived types<commit_after>#include "context.hpp"
#include "expr.hpp"
#include "action.hpp"

namespace pip
{
  context::context(cc::diagnostic_manager& diags,
                   cc::input_manager& in,
                   cc::symbol_table& syms)
    : diags(diags), input(in), syms(syms)
  { }

  symbol*
  context::get_symbol(const char* str)
  {
    return syms.get(str);
  }

  symbol*
  context::get_symbol(const std::string& str)
  {
    return syms.get(str);
  }

	expr*
	context::make_int_expr(type* t, int val)
	{
		return new int_expr(t, val);
	}

	expr*
	context::make_range_expr(type* t, int lo, int hi)
	{
		return new range_expr(t, lo, hi);
	}

	expr*
	context::make_wild_expr(type* t, int val, int mask)
	{
		return new wild_expr(t, val, mask);
	}

	expr*
	context::make_miss_expr(type* t)
	{
		return new miss_expr(t);
	}

	expr*
	context::make_ref_expr(type* t, symbol* id)
	{
		return new ref_expr(t, id);
	}

	expr*
	context::make_field_expr(type* t, expr_kind kind)
	{
		return new field_expr(kind, t);
	}

	action*
	context::make_action(action_kind k)
	{
		switch(k) {
		case ak_advance:
			return new advance_action;
		case ak_copy:
			return new copy_action;
		case ak_set:
			return new set_action;
		case ak_write:
			return new write_action(nullptr);
		case ak_clear:
			return new clear_action;
		case ak_drop:
			return new drop_action;
		case ak_match:
			return new match_action;
		case ak_goto:
			return new goto_action(nullptr);
		case ak_output:
			return new output_action(nullptr);
		default:
			throw std::runtime_error( "Unexpected action\n" );
		}
	}

} // namesapce pip
<|endoftext|>


<commit_before>// Sh: A GPU metaprogramming language.
//
// Copyright 2003-2005 Serious Hack Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA  02110-1301, USA
//////////////////////////////////////////////////////////////////////////////
#ifndef SHPNGIMAGEIMPL_HPP
#define SHPNGIMAGEIMPL_HPP

#include "ShPngImage.hpp"

namespace ShUtil {

using namespace SH;
using namespace std;

struct ShPngImage {
  static float* read_PNG(const string& filename, int& width, int& height,
                         int& elements);
  static void write_PNG(const string& filename, const float* data,
                        int inverse_alpha, int width, int height, int elements);
  static void write_PNG16(const string& filename, const float* data,
                          int inverse_alpha, int width, int height, int elements);
};

/// Copy the contents of the image into a float array
template<typename T>
float* float_copy(const ShTypedImage<T>& image)
{
  int array_length = image.width() * image.height() * image.elements();
  float* float_data = new float[array_length];

  const T* storage_data = image.data();
  for (int i=0; i < array_length; i++) {
    float_data[i] = storage_data[i];
  }

  return float_data;
}

// Public functions

template<typename T>
void load_PNG(ShTypedImage<T>& image, const string& filename)
{
  int width, height, depth;
  float* png_data = ShPngImage::read_PNG(filename, width, height, depth);

  image.set_size(width, height, depth);
  T* storage_data = image.data();

  int array_length = width * height * depth;
  for (int i=0; i < array_length; i++) {
    storage_data[i] = png_data[i];
  }

  delete [] png_data;
}

template<typename T>
void save_PNG(const ShTypedImage<T>& image, const string& filename, int inverse_alpha)
{
  float* float_data = float_copy(image);
  ShPngImage::write_PNG(filename, float_data, inverse_alpha, image.width(), image.height(), image.elements());
  delete [] float_data;
}

template<typename T>
void save_PNG16(const ShTypedImage<T>& image, const string& filename, int inverse_alpha)
{
  float* float_data = float_copy(image);
  ShPngImage::write_PNG16(filename, float_data, inverse_alpha, image.width(), image.height(), image.elements());
  delete [] float_data;
}

} // namespace

#endif // SHPNGIMAGEIMPL_HPP
<commit_msg>DLL Export the ShPngImage class<commit_after>// Sh: A GPU metaprogramming language.
//
// Copyright 2003-2005 Serious Hack Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
// MA  02110-1301, USA
//////////////////////////////////////////////////////////////////////////////
#ifndef SHPNGIMAGEIMPL_HPP
#define SHPNGIMAGEIMPL_HPP

#include "ShPngImage.hpp"
#include "ShDllExport.hpp"

namespace ShUtil {

using namespace SH;
using namespace std;

struct
SH_DLLEXPORT ShPngImage {
  static float* read_PNG(const string& filename, int& width, int& height,
                         int& elements);
  static void write_PNG(const string& filename, const float* data,
                        int inverse_alpha, int width, int height, int elements);
  static void write_PNG16(const string& filename, const float* data,
                          int inverse_alpha, int width, int height, int elements);
};

/// Copy the contents of the image into a float array
template<typename T>
float* float_copy(const ShTypedImage<T>& image)
{
  int array_length = image.width() * image.height() * image.elements();
  float* float_data = new float[array_length];

  const T* storage_data = image.data();
  for (int i=0; i < array_length; i++) {
    float_data[i] = storage_data[i];
  }

  return float_data;
}

// Public functions

template<typename T>
void load_PNG(ShTypedImage<T>& image, const string& filename)
{
  int width, height, depth;
  float* png_data = ShPngImage::read_PNG(filename, width, height, depth);

  image.set_size(width, height, depth);
  T* storage_data = image.data();

  int array_length = width * height * depth;
  for (int i=0; i < array_length; i++) {
    storage_data[i] = png_data[i];
  }

  delete [] png_data;
}

template<typename T>
void save_PNG(const ShTypedImage<T>& image, const string& filename, int inverse_alpha)
{
  float* float_data = float_copy(image);
  ShPngImage::write_PNG(filename, float_data, inverse_alpha, image.width(), image.height(), image.elements());
  delete [] float_data;
}

template<typename T>
void save_PNG16(const ShTypedImage<T>& image, const string& filename, int inverse_alpha)
{
  float* float_data = float_copy(image);
  ShPngImage::write_PNG16(filename, float_data, inverse_alpha, image.width(), image.height(), image.elements());
  delete [] float_data;
}

} // namespace

#endif // SHPNGIMAGEIMPL_HPP
<|endoftext|>


<commit_before>#include <cstdlib>
#include <iostream>
#include <thread>
#include <utility>
#include <boost/asio.hpp>

#include <boost/algorithm/string/predicate.hpp>
#include "../common/rfc822.h"

#include "session.h"

namespace asio = boost::asio;
using asio::ip::tcp;

void server(asio::io_service& io_service, unsigned short port)
{
  tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
  for (;;)
  {
    tcp::socket sock(io_service);
    a.accept(sock);
    std::thread(session, std::move(sock)).detach();
  }
}

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: sync_server <port>\n";
      return 1;
    }

    asio::io_service io_service;

    server(io_service, std::atoi(argv[1]));
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
<commit_msg>Compile sync_server with thread safe spirit.<commit_after>#define BOOST_SPIRIT_THREADSAFE
#define PHOENIX_THREADSAFE

#include <cstdlib>
#include <iostream>
#include <thread>
#include <utility>
#include <boost/asio.hpp>

#include <boost/algorithm/string/predicate.hpp>
#include "../common/rfc822.h"

#include "session.h"

namespace asio = boost::asio;
using asio::ip::tcp;

void server(asio::io_service& io_service, unsigned short port)
{
  tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
  for (;;)
  {
    tcp::socket sock(io_service);
    a.accept(sock);
    std::thread(session, std::move(sock)).detach();
  }
}

int main(int argc, char* argv[])
{
  try
  {
    if (argc != 2)
    {
      std::cerr << "Usage: sync_server <port>\n";
      return 1;
    }

    asio::io_service io_service;

    server(io_service, std::atoi(argv[1]));
  }
  catch (std::exception& e)
  {
    std::cerr << "Exception: " << e.what() << "\n";
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "cnn/lstm.h"

#include <string>
#include <cassert>
#include <vector>
#include <iostream>

#include "cnn/nodes.h"

using namespace std;
using namespace cnn::expr;

namespace cnn {

enum { X2I, H2I, C2I, BI, X2O, H2O, C2O, BO, X2C, H2C, BC };

LSTMBuilder::LSTMBuilder(unsigned layers,
                         unsigned input_dim,
                         unsigned hidden_dim,
                         Model* model) : layers(layers) {
  unsigned layer_input_dim = input_dim;
  for (unsigned i = 0; i < layers; ++i) {
    // i
    Parameters* p_x2i = model->add_parameters({hidden_dim, layer_input_dim});
    Parameters* p_h2i = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_c2i = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_bi = model->add_parameters({hidden_dim});

    // o
    Parameters* p_x2o = model->add_parameters({hidden_dim, layer_input_dim});
    Parameters* p_h2o = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_c2o = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_bo = model->add_parameters({hidden_dim});

    // c
    Parameters* p_x2c = model->add_parameters({hidden_dim, layer_input_dim});
    Parameters* p_h2c = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_bc = model->add_parameters({hidden_dim});
    layer_input_dim = hidden_dim;  // output (hidden) from 1st layer is input to next

    vector<Parameters*> ps = {p_x2i, p_h2i, p_c2i, p_bi, p_x2o, p_h2o, p_c2o, p_bo, p_x2c, p_h2c, p_bc};
    params.push_back(ps);
  }  // layers
}

void LSTMBuilder::new_graph_impl(ComputationGraph& cg){
  param_vars.clear();

  for (unsigned i = 0; i < layers; ++i){
    auto& p = params[i];

    //i
    Expression i_x2i = parameter(cg,p[X2I]);
    Expression i_h2i = parameter(cg,p[H2I]);
    Expression i_c2i = parameter(cg,p[C2I]);
    Expression i_bi = parameter(cg,p[BI]);
    //o
    Expression i_x2o = parameter(cg,p[X2O]);
    Expression i_h2o = parameter(cg,p[H2O]);
    Expression i_c2o = parameter(cg,p[C2O]);
    Expression i_bo = parameter(cg,p[BO]);
    //c
    Expression i_x2c = parameter(cg,p[X2C]);
    Expression i_h2c = parameter(cg,p[H2C]);
    Expression i_bc = parameter(cg,p[BC]);

    vector<Expression> vars = {i_x2i, i_h2i, i_c2i, i_bi, i_x2o, i_h2o, i_c2o, i_bo, i_x2c, i_h2c, i_bc};
    param_vars.push_back(vars);
  }
}

// layout: 0..layers = c
//         layers+1..2*layers = h
void LSTMBuilder::start_new_sequence_impl(const vector<Expression>& hinit) {
  h.clear();
  c.clear();
  if (hinit.size() > 0) {
    assert(layers*2 == hinit.size());
    h0.resize(layers);
    c0.resize(layers);
    for (unsigned i = 0; i < layers; ++i) {
      c0[i] = hinit[i];
      h0[i] = hinit[i + layers];
    }
    has_initial_state = true;
  } else {
    has_initial_state = false;
  }
}

Expression LSTMBuilder::add_input_impl(int prev, const Expression& x) {
  h.push_back(vector<Expression>(layers));
  c.push_back(vector<Expression>(layers));
  vector<Expression>& ht = h.back();
  vector<Expression>& ct = c.back();
  Expression in = x;
  for (unsigned i = 0; i < layers; ++i) {
    const vector<Expression>& vars = param_vars[i];
    Expression i_h_tm1, i_c_tm1;
    bool has_prev_state = (prev >= 0 || has_initial_state);
    if (prev < 0) {
      if (has_initial_state) {
        // intial value for h and c at timestep 0 in layer i
        // defaults to zero matrix input if not set in add_parameter_edges
        i_h_tm1 = h0[i];
        i_c_tm1 = c0[i];
      }
    } else {  // t > 0
      i_h_tm1 = h[prev][i];
      i_c_tm1 = c[prev][i];
    }
    // apply dropout according to http://arxiv.org/pdf/1409.2329v5.pdf
    if (dropout_rate) in = dropout(in, dropout_rate);
    // input
    Expression i_ait;
    if (has_prev_state)
      i_ait = affine_transform({vars[BI], vars[X2I], in, vars[H2I], i_h_tm1, vars[C2I], i_c_tm1});
    else
      i_ait = affine_transform({vars[BI], vars[X2I], in});
    Expression i_it = logistic(i_ait);
    // forget
    Expression i_ft = 1.f - i_it;
    // write memory cell
    Expression i_awt;
    if (has_prev_state)
      i_awt = affine_transform({vars[BC], vars[X2C], in, vars[H2C], i_h_tm1});
    else
      i_awt = affine_transform({vars[BC], vars[X2C], in});
    Expression i_wt = tanh(i_awt);
    // output
    if (has_prev_state) {
      Expression i_nwt = cwise_multiply(i_it,i_wt);
      Expression i_crt = cwise_multiply(i_ft,i_c_tm1);
      ct[i] = i_crt + i_nwt;
    } else {
      ct[i] = cwise_multiply(i_it,i_wt);
    }

    Expression i_aot;
    if (has_prev_state)
      i_aot = affine_transform({vars[BO], vars[X2O], in, vars[H2O], i_h_tm1, vars[C2O], ct[i]});
    else
      i_aot = affine_transform({vars[BO], vars[X2O], in});
    Expression i_ot = logistic(i_aot);
    Expression ph_t = tanh(ct[i]);
    in = ht[i] = cwise_multiply(i_ot,ph_t);
  }
  if (dropout_rate) return dropout(ht.back(), dropout_rate);
    else return ht.back();
}

void LSTMBuilder::copy(const RNNBuilder & rnn) {
  const LSTMBuilder & rnn_lstm = (const LSTMBuilder&)rnn;
  assert(params.size() == rnn_lstm.params.size());
  for(size_t i = 0; i < params.size(); ++i)
      for(size_t j = 0; j < params[i].size(); ++j)
        params[i][j]->copy(*rnn_lstm.params[i][j]);
}

} // namespace cnn
<commit_msg>Initialize dropout_rate to 0.0 in LSTM Builder by default. Previously it was uninitialized and could result in very strange behavior<commit_after>#include "cnn/lstm.h"

#include <string>
#include <cassert>
#include <vector>
#include <iostream>

#include "cnn/nodes.h"

using namespace std;
using namespace cnn::expr;

namespace cnn {

enum { X2I, H2I, C2I, BI, X2O, H2O, C2O, BO, X2C, H2C, BC };

LSTMBuilder::LSTMBuilder(unsigned layers,
                         unsigned input_dim,
                         unsigned hidden_dim,
                         Model* model) : layers(layers) {
  unsigned layer_input_dim = input_dim;
  for (unsigned i = 0; i < layers; ++i) {
    // i
    Parameters* p_x2i = model->add_parameters({hidden_dim, layer_input_dim});
    Parameters* p_h2i = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_c2i = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_bi = model->add_parameters({hidden_dim});

    // o
    Parameters* p_x2o = model->add_parameters({hidden_dim, layer_input_dim});
    Parameters* p_h2o = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_c2o = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_bo = model->add_parameters({hidden_dim});

    // c
    Parameters* p_x2c = model->add_parameters({hidden_dim, layer_input_dim});
    Parameters* p_h2c = model->add_parameters({hidden_dim, hidden_dim});
    Parameters* p_bc = model->add_parameters({hidden_dim});
    layer_input_dim = hidden_dim;  // output (hidden) from 1st layer is input to next

    vector<Parameters*> ps = {p_x2i, p_h2i, p_c2i, p_bi, p_x2o, p_h2o, p_c2o, p_bo, p_x2c, p_h2c, p_bc};
    params.push_back(ps);
  }  // layers
  dropout_rate = 0.0f;
}

void LSTMBuilder::new_graph_impl(ComputationGraph& cg){
  param_vars.clear();

  for (unsigned i = 0; i < layers; ++i){
    auto& p = params[i];

    //i
    Expression i_x2i = parameter(cg,p[X2I]);
    Expression i_h2i = parameter(cg,p[H2I]);
    Expression i_c2i = parameter(cg,p[C2I]);
    Expression i_bi = parameter(cg,p[BI]);
    //o
    Expression i_x2o = parameter(cg,p[X2O]);
    Expression i_h2o = parameter(cg,p[H2O]);
    Expression i_c2o = parameter(cg,p[C2O]);
    Expression i_bo = parameter(cg,p[BO]);
    //c
    Expression i_x2c = parameter(cg,p[X2C]);
    Expression i_h2c = parameter(cg,p[H2C]);
    Expression i_bc = parameter(cg,p[BC]);

    vector<Expression> vars = {i_x2i, i_h2i, i_c2i, i_bi, i_x2o, i_h2o, i_c2o, i_bo, i_x2c, i_h2c, i_bc};
    param_vars.push_back(vars);
  }
}

// layout: 0..layers = c
//         layers+1..2*layers = h
void LSTMBuilder::start_new_sequence_impl(const vector<Expression>& hinit) {
  h.clear();
  c.clear();
  if (hinit.size() > 0) {
    assert(layers*2 == hinit.size());
    h0.resize(layers);
    c0.resize(layers);
    for (unsigned i = 0; i < layers; ++i) {
      c0[i] = hinit[i];
      h0[i] = hinit[i + layers];
    }
    has_initial_state = true;
  } else {
    has_initial_state = false;
  }
}

Expression LSTMBuilder::add_input_impl(int prev, const Expression& x) {
  h.push_back(vector<Expression>(layers));
  c.push_back(vector<Expression>(layers));
  vector<Expression>& ht = h.back();
  vector<Expression>& ct = c.back();
  Expression in = x;
  for (unsigned i = 0; i < layers; ++i) {
    const vector<Expression>& vars = param_vars[i];
    Expression i_h_tm1, i_c_tm1;
    bool has_prev_state = (prev >= 0 || has_initial_state);
    if (prev < 0) {
      if (has_initial_state) {
        // intial value for h and c at timestep 0 in layer i
        // defaults to zero matrix input if not set in add_parameter_edges
        i_h_tm1 = h0[i];
        i_c_tm1 = c0[i];
      }
    } else {  // t > 0
      i_h_tm1 = h[prev][i];
      i_c_tm1 = c[prev][i];
    }
    // apply dropout according to http://arxiv.org/pdf/1409.2329v5.pdf
    if (dropout_rate) in = dropout(in, dropout_rate);
    // input
    Expression i_ait;
    if (has_prev_state)
      i_ait = affine_transform({vars[BI], vars[X2I], in, vars[H2I], i_h_tm1, vars[C2I], i_c_tm1});
    else
      i_ait = affine_transform({vars[BI], vars[X2I], in});
    Expression i_it = logistic(i_ait);
    // forget
    Expression i_ft = 1.f - i_it;
    // write memory cell
    Expression i_awt;
    if (has_prev_state)
      i_awt = affine_transform({vars[BC], vars[X2C], in, vars[H2C], i_h_tm1});
    else
      i_awt = affine_transform({vars[BC], vars[X2C], in});
    Expression i_wt = tanh(i_awt);
    // output
    if (has_prev_state) {
      Expression i_nwt = cwise_multiply(i_it,i_wt);
      Expression i_crt = cwise_multiply(i_ft,i_c_tm1);
      ct[i] = i_crt + i_nwt;
    } else {
      ct[i] = cwise_multiply(i_it,i_wt);
    }

    Expression i_aot;
    if (has_prev_state)
      i_aot = affine_transform({vars[BO], vars[X2O], in, vars[H2O], i_h_tm1, vars[C2O], ct[i]});
    else
      i_aot = affine_transform({vars[BO], vars[X2O], in});
    Expression i_ot = logistic(i_aot);
    Expression ph_t = tanh(ct[i]);
    in = ht[i] = cwise_multiply(i_ot,ph_t);
  }
  if (dropout_rate) return dropout(ht.back(), dropout_rate);
    else return ht.back();
}

void LSTMBuilder::copy(const RNNBuilder & rnn) {
  const LSTMBuilder & rnn_lstm = (const LSTMBuilder&)rnn;
  assert(params.size() == rnn_lstm.params.size());
  for(size_t i = 0; i < params.size(); ++i)
      for(size_t j = 0; j < params[i].size(); ++j)
        params[i][j]->copy(*rnn_lstm.params[i][j]);
}

} // namespace cnn
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: WeakListenerAdapter.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-05-22 19:06:31 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "WeakListenerAdapter.hxx"

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

namespace chart
{

WeakModifyListenerAdapter::WeakModifyListenerAdapter(
    const Reference< util::XModifyListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::util::XModifyListener >( xListener )
{}

WeakModifyListenerAdapter::WeakModifyListenerAdapter(
    const uno::WeakReference< util::XModifyListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::util::XModifyListener >( xListener )
{}

WeakModifyListenerAdapter::~WeakModifyListenerAdapter()
{}

void SAL_CALL WeakModifyListenerAdapter::modified( const lang::EventObject& aEvent )
    throw (uno::RuntimeException)
{
    Reference< util::XModifyListener > xModListener( getListener() );
    if( xModListener.is())
        xModListener->modified( aEvent );
}

// --------------------------------------------------------------------------------

WeakSelectionChangeListenerAdapter::WeakSelectionChangeListenerAdapter(
    const Reference< view::XSelectionChangeListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::view::XSelectionChangeListener >( xListener )
{}

WeakSelectionChangeListenerAdapter::WeakSelectionChangeListenerAdapter(
    const uno::WeakReference< view::XSelectionChangeListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::view::XSelectionChangeListener >( xListener )
{}

WeakSelectionChangeListenerAdapter::~WeakSelectionChangeListenerAdapter()
{}

void SAL_CALL WeakSelectionChangeListenerAdapter::selectionChanged( const lang::EventObject& aEvent )
    throw (uno::RuntimeException)
{
    Reference< view::XSelectionChangeListener > xSelChgListener( getListener() );
    if( xSelChgListener.is())
        xSelChgListener->selectionChanged( aEvent );
}

} //  namespace chart
<commit_msg>INTEGRATION: CWS changefileheader (1.2.126); FILE MERGED 2008/03/28 16:44:26 rt 1.2.126.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: WeakListenerAdapter.cxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "WeakListenerAdapter.hxx"

using namespace ::com::sun::star;

using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::rtl::OUString;

namespace chart
{

WeakModifyListenerAdapter::WeakModifyListenerAdapter(
    const Reference< util::XModifyListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::util::XModifyListener >( xListener )
{}

WeakModifyListenerAdapter::WeakModifyListenerAdapter(
    const uno::WeakReference< util::XModifyListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::util::XModifyListener >( xListener )
{}

WeakModifyListenerAdapter::~WeakModifyListenerAdapter()
{}

void SAL_CALL WeakModifyListenerAdapter::modified( const lang::EventObject& aEvent )
    throw (uno::RuntimeException)
{
    Reference< util::XModifyListener > xModListener( getListener() );
    if( xModListener.is())
        xModListener->modified( aEvent );
}

// --------------------------------------------------------------------------------

WeakSelectionChangeListenerAdapter::WeakSelectionChangeListenerAdapter(
    const Reference< view::XSelectionChangeListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::view::XSelectionChangeListener >( xListener )
{}

WeakSelectionChangeListenerAdapter::WeakSelectionChangeListenerAdapter(
    const uno::WeakReference< view::XSelectionChangeListener > & xListener ) :
        WeakListenerAdapter< ::com::sun::star::view::XSelectionChangeListener >( xListener )
{}

WeakSelectionChangeListenerAdapter::~WeakSelectionChangeListenerAdapter()
{}

void SAL_CALL WeakSelectionChangeListenerAdapter::selectionChanged( const lang::EventObject& aEvent )
    throw (uno::RuntimeException)
{
    Reference< view::XSelectionChangeListener > xSelChgListener( getListener() );
    if( xSelChgListener.is())
        xSelChgListener->selectionChanged( aEvent );
}

} //  namespace chart
<|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 "chrome/browser/alternate_nav_url_fetcher.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"

AlternateNavURLFetcher::AlternateNavURLFetcher(
    const GURL& alternate_nav_url)
    : LinkInfoBarDelegate(NULL),
      alternate_nav_url_(alternate_nav_url),
      controller_(NULL),
      state_(NOT_STARTED),
      navigated_to_entry_(false),
      infobar_contents_(NULL) {
  registrar_.Add(this, NotificationType::NAV_ENTRY_PENDING,
                 NotificationService::AllSources());
}

void AlternateNavURLFetcher::Observe(NotificationType type,
                                     const NotificationSource& source,
                                     const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::NAV_ENTRY_PENDING:
      controller_ = Source<NavigationController>(source).ptr();
      DCHECK(controller_->pending_entry());

      // Unregister for this notification now that we're pending, and start
      // listening for the corresponding commit. We also need to listen for the
      // tab close command since that means the load will never commit!
      registrar_.Remove(this, NotificationType::NAV_ENTRY_PENDING,
                        NotificationService::AllSources());
      registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                     Source<NavigationController>(controller_));

      DCHECK_EQ(NOT_STARTED, state_);
      state_ = IN_PROGRESS;
      fetcher_.reset(new URLFetcher(GURL(alternate_nav_url_), URLFetcher::HEAD,
                                    this));
      fetcher_->set_request_context(
          controller_->profile()->GetRequestContext());
      fetcher_->Start();
      break;

    case NotificationType::NAV_ENTRY_COMMITTED:
      // The page was navigated, we can show the infobar now if necessary.
      registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
                        Source<NavigationController>(controller_));
      navigated_to_entry_ = true;
      ShowInfobarIfPossible();
      break;

    default:
      NOTREACHED();
  }
}

void AlternateNavURLFetcher::OnURLFetchComplete(const URLFetcher* source,
                                                const GURL& url,
                                                const URLRequestStatus& status,
                                                int response_code,
                                                const ResponseCookies& cookies,
                                                const std::string& data) {
  DCHECK(fetcher_.get() == source);
  if (status.is_success() &&
      // HTTP 2xx, 401, and 407 all indicate that the target address exists.
      (((response_code / 100) == 2) ||
       (response_code == 401) || (response_code == 407))) {
    state_ = SUCCEEDED;
    ShowInfobarIfPossible();
  } else {
    state_ = FAILED;
  }
}

std::wstring AlternateNavURLFetcher::GetMessageTextWithOffset(
    size_t* link_offset) const {
  const std::wstring label = l10n_util::GetStringF(
      IDS_ALTERNATE_NAV_URL_VIEW_LABEL, std::wstring(), link_offset);
  DCHECK(*link_offset != std::wstring::npos);
  return label;
}

std::wstring AlternateNavURLFetcher::GetLinkText() const {
  return UTF8ToWide(alternate_nav_url_.spec());
}

SkBitmap* AlternateNavURLFetcher::GetIcon() const {
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_INFOBAR_ALT_NAV_URL);
}

bool AlternateNavURLFetcher::LinkClicked(WindowOpenDisposition disposition) {
  infobar_contents_->OpenURL(
      alternate_nav_url_, GURL(), disposition,
      // Pretend the user typed this URL, so that navigating to
      // it will be the default action when it's typed again in
      // the future.
      PageTransition::TYPED);

  // We should always close, even if the navigation did not occur within this
  // TabContents.
  return true;
}

void AlternateNavURLFetcher::InfoBarClosed() {
  delete this;
}

void AlternateNavURLFetcher::ShowInfobarIfPossible() {
  if (!navigated_to_entry_ || state_ != SUCCEEDED)
    return;

  infobar_contents_ = controller_->tab_contents();
  StoreActiveEntryUniqueID(infobar_contents_);
  // We will be deleted when the InfoBar is destroyed. (See InfoBarClosed).
  infobar_contents_->AddInfoBar(this);
}
<commit_msg>A crasher can happen in the AlternateNavURLFetcher if the fetch finishes after the tab has been closed. At that point the navigation controller the AlternateNavURLFetcher has been deleted and should not be accessed. This CL also addresses a memory leak that would happen when the fetch would fail.<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 "chrome/browser/alternate_nav_url_fetcher.h"

#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/common/notification_service.h"
#include "grit/generated_resources.h"

AlternateNavURLFetcher::AlternateNavURLFetcher(
    const GURL& alternate_nav_url)
    : LinkInfoBarDelegate(NULL),
      alternate_nav_url_(alternate_nav_url),
      controller_(NULL),
      state_(NOT_STARTED),
      navigated_to_entry_(false),
      infobar_contents_(NULL) {
  registrar_.Add(this, NotificationType::NAV_ENTRY_PENDING,
                 NotificationService::AllSources());
}

void AlternateNavURLFetcher::Observe(NotificationType type,
                                     const NotificationSource& source,
                                     const NotificationDetails& details) {
  switch (type.value) {
    case NotificationType::NAV_ENTRY_PENDING:
      controller_ = Source<NavigationController>(source).ptr();
      DCHECK(controller_->pending_entry());

      // Unregister for this notification now that we're pending, and start
      // listening for the corresponding commit. We also need to listen for the
      // tab close command since that means the load will never commit!
      registrar_.Remove(this, NotificationType::NAV_ENTRY_PENDING,
                        NotificationService::AllSources());
      registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
                     Source<NavigationController>(controller_));
      registrar_.Add(this, NotificationType::TAB_CLOSED,
                     Source<NavigationController>(controller_));

      DCHECK_EQ(NOT_STARTED, state_);
      state_ = IN_PROGRESS;
      fetcher_.reset(new URLFetcher(GURL(alternate_nav_url_), URLFetcher::HEAD,
                                    this));
      fetcher_->set_request_context(
          controller_->profile()->GetRequestContext());
      fetcher_->Start();
      break;

    case NotificationType::NAV_ENTRY_COMMITTED:
      // The page was navigated, we can show the infobar now if necessary.
      registrar_.Remove(this, NotificationType::NAV_ENTRY_COMMITTED,
                        Source<NavigationController>(controller_));
      navigated_to_entry_ = true;
      ShowInfobarIfPossible();
      break;

    case NotificationType::TAB_CLOSED:
      // We have been closed. In order to prevent the URLFetcher from trying to
      // access the controller that will be invalid, we delete ourselves.
      // This deletes the URLFetcher and insures its callback won't be called.
      delete this;
      break;

    default:
      NOTREACHED();
  }
}

void AlternateNavURLFetcher::OnURLFetchComplete(const URLFetcher* source,
                                                const GURL& url,
                                                const URLRequestStatus& status,
                                                int response_code,
                                                const ResponseCookies& cookies,
                                                const std::string& data) {
  DCHECK(fetcher_.get() == source);
  if (status.is_success() &&
      // HTTP 2xx, 401, and 407 all indicate that the target address exists.
      (((response_code / 100) == 2) ||
       (response_code == 401) || (response_code == 407))) {
    state_ = SUCCEEDED;
  } else {
    state_ = FAILED;
  }
  ShowInfobarIfPossible();
}

std::wstring AlternateNavURLFetcher::GetMessageTextWithOffset(
    size_t* link_offset) const {
  const std::wstring label = l10n_util::GetStringF(
      IDS_ALTERNATE_NAV_URL_VIEW_LABEL, std::wstring(), link_offset);
  DCHECK(*link_offset != std::wstring::npos);
  return label;
}

std::wstring AlternateNavURLFetcher::GetLinkText() const {
  return UTF8ToWide(alternate_nav_url_.spec());
}

SkBitmap* AlternateNavURLFetcher::GetIcon() const {
  return ResourceBundle::GetSharedInstance().GetBitmapNamed(
      IDR_INFOBAR_ALT_NAV_URL);
}

bool AlternateNavURLFetcher::LinkClicked(WindowOpenDisposition disposition) {
  infobar_contents_->OpenURL(
      alternate_nav_url_, GURL(), disposition,
      // Pretend the user typed this URL, so that navigating to
      // it will be the default action when it's typed again in
      // the future.
      PageTransition::TYPED);

  // We should always close, even if the navigation did not occur within this
  // TabContents.
  return true;
}

void AlternateNavURLFetcher::InfoBarClosed() {
  delete this;
}

void AlternateNavURLFetcher::ShowInfobarIfPossible() {
  if (!navigated_to_entry_ || state_ != SUCCEEDED) {
    if (state_ == FAILED)
      delete this;
    return;
  }

  infobar_contents_ = controller_->tab_contents();
  StoreActiveEntryUniqueID(infobar_contents_);
  // We will be deleted when the InfoBar is destroyed. (See InfoBarClosed).
  infobar_contents_->AddInfoBar(this);
}
<|endoftext|>


<commit_before>// 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 "chrome/browser/chrome_browser_main_linux.h"

#if !defined(OS_CHROMEOS)
#include "chrome/browser/storage_monitor/storage_monitor_linux.h"
#include "content/public/browser/browser_thread.h"
#endif

#if defined(USE_LINUX_BREAKPAD)
#include <stdlib.h>

#include "base/command_line.h"
#include "base/linux_util.h"
#include "base/prefs/pref_service.h"
#include "chrome/app/breakpad_linux.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/pref_names.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/common/chrome_version_info.h"
#include "chromeos/chromeos_switches.h"
#endif

#endif  // defined(USE_LINUX_BREAKPAD)

namespace {

#if defined(USE_LINUX_BREAKPAD)
#if !defined(OS_CHROMEOS)
void GetLinuxDistroCallback() {
  base::GetLinuxDistro();  // Initialize base::linux_distro if needed.
}
#endif

bool IsCrashReportingEnabled(const PrefService* local_state) {
  // Check whether we should initialize the crash reporter. It may be disabled
  // through configuration policy or user preference. It must be disabled for
  // Guest mode on Chrome OS in Stable channel.
  // Also allow crash reporting to be enabled with a command-line flag if the
  // crash service is under control of the user. It is used by QA
  // testing infrastructure to switch on generation of crash reports.
  bool use_switch = true;

  // Convert #define to a variable so that we can use if() rather than
  // #if below and so at least compile-test the Chrome code in
  // Chromium builds.
#if defined(GOOGLE_CHROME_BUILD)
  bool is_chrome_build = true;
#else
  bool is_chrome_build = false;
#endif

  // Check these settings in Chrome builds only, to reduce the chance
  // that we accidentally upload crash dumps from Chromium builds.
  bool breakpad_enabled = false;
  if (is_chrome_build) {
#if defined(OS_CHROMEOS)
    bool is_guest_session = CommandLine::ForCurrentProcess()->HasSwitch(
        chromeos::switches::kGuestSession);
    bool is_stable_channel =
        chrome::VersionInfo::GetChannel() ==
        chrome::VersionInfo::CHANNEL_STABLE;
    // TODO(pastarmovj): Consider the TrustedGet here.
    bool reporting_enabled;
    chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
                                              &reporting_enabled);
    breakpad_enabled =
        !(is_guest_session && is_stable_channel) && reporting_enabled;
#else
    const PrefService::Preference* metrics_reporting_enabled =
        local_state->FindPreference(prefs::kMetricsReportingEnabled);
    CHECK(metrics_reporting_enabled);
    breakpad_enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled);
    use_switch = metrics_reporting_enabled->IsUserModifiable();
#endif  // defined(OS_CHROMEOS)
  }

  if (use_switch) {
    // Linux Breakpad interferes with the debug stack traces produced
    // by EnableInProcessStackDumping(), used in browser_tests, so we
    // do not allow CHROME_HEADLESS=1 to enable Breakpad in Chromium
    // because the buildbots have CHROME_HEADLESS set.  However, we
    // allow CHROME_HEADLESS to enable Breakpad in Chrome for
    // compatibility with Breakpad/Chrome tests that may rely on this.
    // TODO(mseaborn): Change tests to use --enable-crash-reporter-for-testing
    // instead.
    if (is_chrome_build && !breakpad_enabled)
      breakpad_enabled = getenv(env_vars::kHeadless) != NULL;
    if (!breakpad_enabled)
      breakpad_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableCrashReporterForTesting);
  }

  return breakpad_enabled;
}
#endif  // defined(USE_LINUX_BREAKPAD)

}  // namespace

ChromeBrowserMainPartsLinux::ChromeBrowserMainPartsLinux(
    const content::MainFunctionParams& parameters)
    : ChromeBrowserMainPartsPosix(parameters) {
}

ChromeBrowserMainPartsLinux::~ChromeBrowserMainPartsLinux() {
}

void ChromeBrowserMainPartsLinux::PreProfileInit() {
#if defined(USE_LINUX_BREAKPAD)
#if !defined(OS_CHROMEOS)
  // Needs to be called after we have chrome::DIR_USER_DATA and
  // g_browser_process.  This happens in PreCreateThreads.
  content::BrowserThread::PostTask(content::BrowserThread::FILE,
                                   FROM_HERE,
                                   base::Bind(&GetLinuxDistroCallback));
#endif

  if (IsCrashReportingEnabled(local_state()))
    InitCrashReporter();
#endif

#if !defined(OS_CHROMEOS)
  const base::FilePath kDefaultMtabPath("/etc/mtab");
  storage_monitor_.reset(new chrome::StorageMonitorLinux(kDefaultMtabPath));
#endif

  ChromeBrowserMainPartsPosix::PreProfileInit();
}

void ChromeBrowserMainPartsLinux::PostProfileInit() {
  ChromeBrowserMainPartsPosix::PostProfileInit();

#if defined(USE_LINUX_BREAKPAD)
  g_browser_process->metrics_service()->RecordBreakpadRegistration(
      IsCrashReporterEnabled());
#else
  g_browser_process->metrics_service()->RecordBreakpadRegistration(false);
#endif
}

void ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() {
  ChromeBrowserMainPartsPosix::PostMainMessageLoopRun();

#if !defined(OS_CHROMEOS)
  // Delete it now. Otherwise the FILE thread would be gone when we try to
  // release it in the dtor and Valgrind would report a leak on almost every
  // single browser_test.
  storage_monitor_.reset();
#endif
}
<commit_msg>linux: Fix misplaced includes from r210884.<commit_after>// 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 "chrome/browser/chrome_browser_main_linux.h"

#include "chrome/browser/browser_process.h"
#include "chrome/browser/metrics/metrics_service.h"

#if !defined(OS_CHROMEOS)
#include "chrome/browser/storage_monitor/storage_monitor_linux.h"
#include "content/public/browser/browser_thread.h"
#endif

#if defined(USE_LINUX_BREAKPAD)
#include <stdlib.h>

#include "base/command_line.h"
#include "base/linux_util.h"
#include "base/prefs/pref_service.h"
#include "chrome/app/breakpad_linux.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/env_vars.h"
#include "chrome/common/pref_names.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/chromeos/settings/cros_settings_names.h"
#include "chrome/common/chrome_version_info.h"
#include "chromeos/chromeos_switches.h"
#endif

#endif  // defined(USE_LINUX_BREAKPAD)

namespace {

#if defined(USE_LINUX_BREAKPAD)
#if !defined(OS_CHROMEOS)
void GetLinuxDistroCallback() {
  base::GetLinuxDistro();  // Initialize base::linux_distro if needed.
}
#endif

bool IsCrashReportingEnabled(const PrefService* local_state) {
  // Check whether we should initialize the crash reporter. It may be disabled
  // through configuration policy or user preference. It must be disabled for
  // Guest mode on Chrome OS in Stable channel.
  // Also allow crash reporting to be enabled with a command-line flag if the
  // crash service is under control of the user. It is used by QA
  // testing infrastructure to switch on generation of crash reports.
  bool use_switch = true;

  // Convert #define to a variable so that we can use if() rather than
  // #if below and so at least compile-test the Chrome code in
  // Chromium builds.
#if defined(GOOGLE_CHROME_BUILD)
  bool is_chrome_build = true;
#else
  bool is_chrome_build = false;
#endif

  // Check these settings in Chrome builds only, to reduce the chance
  // that we accidentally upload crash dumps from Chromium builds.
  bool breakpad_enabled = false;
  if (is_chrome_build) {
#if defined(OS_CHROMEOS)
    bool is_guest_session = CommandLine::ForCurrentProcess()->HasSwitch(
        chromeos::switches::kGuestSession);
    bool is_stable_channel =
        chrome::VersionInfo::GetChannel() ==
        chrome::VersionInfo::CHANNEL_STABLE;
    // TODO(pastarmovj): Consider the TrustedGet here.
    bool reporting_enabled;
    chromeos::CrosSettings::Get()->GetBoolean(chromeos::kStatsReportingPref,
                                              &reporting_enabled);
    breakpad_enabled =
        !(is_guest_session && is_stable_channel) && reporting_enabled;
#else
    const PrefService::Preference* metrics_reporting_enabled =
        local_state->FindPreference(prefs::kMetricsReportingEnabled);
    CHECK(metrics_reporting_enabled);
    breakpad_enabled = local_state->GetBoolean(prefs::kMetricsReportingEnabled);
    use_switch = metrics_reporting_enabled->IsUserModifiable();
#endif  // defined(OS_CHROMEOS)
  }

  if (use_switch) {
    // Linux Breakpad interferes with the debug stack traces produced
    // by EnableInProcessStackDumping(), used in browser_tests, so we
    // do not allow CHROME_HEADLESS=1 to enable Breakpad in Chromium
    // because the buildbots have CHROME_HEADLESS set.  However, we
    // allow CHROME_HEADLESS to enable Breakpad in Chrome for
    // compatibility with Breakpad/Chrome tests that may rely on this.
    // TODO(mseaborn): Change tests to use --enable-crash-reporter-for-testing
    // instead.
    if (is_chrome_build && !breakpad_enabled)
      breakpad_enabled = getenv(env_vars::kHeadless) != NULL;
    if (!breakpad_enabled)
      breakpad_enabled = CommandLine::ForCurrentProcess()->HasSwitch(
            switches::kEnableCrashReporterForTesting);
  }

  return breakpad_enabled;
}
#endif  // defined(USE_LINUX_BREAKPAD)

}  // namespace

ChromeBrowserMainPartsLinux::ChromeBrowserMainPartsLinux(
    const content::MainFunctionParams& parameters)
    : ChromeBrowserMainPartsPosix(parameters) {
}

ChromeBrowserMainPartsLinux::~ChromeBrowserMainPartsLinux() {
}

void ChromeBrowserMainPartsLinux::PreProfileInit() {
#if defined(USE_LINUX_BREAKPAD)
#if !defined(OS_CHROMEOS)
  // Needs to be called after we have chrome::DIR_USER_DATA and
  // g_browser_process.  This happens in PreCreateThreads.
  content::BrowserThread::PostTask(content::BrowserThread::FILE,
                                   FROM_HERE,
                                   base::Bind(&GetLinuxDistroCallback));
#endif

  if (IsCrashReportingEnabled(local_state()))
    InitCrashReporter();
#endif

#if !defined(OS_CHROMEOS)
  const base::FilePath kDefaultMtabPath("/etc/mtab");
  storage_monitor_.reset(new chrome::StorageMonitorLinux(kDefaultMtabPath));
#endif

  ChromeBrowserMainPartsPosix::PreProfileInit();
}

void ChromeBrowserMainPartsLinux::PostProfileInit() {
  ChromeBrowserMainPartsPosix::PostProfileInit();

#if defined(USE_LINUX_BREAKPAD)
  g_browser_process->metrics_service()->RecordBreakpadRegistration(
      IsCrashReporterEnabled());
#else
  g_browser_process->metrics_service()->RecordBreakpadRegistration(false);
#endif
}

void ChromeBrowserMainPartsLinux::PostMainMessageLoopRun() {
  ChromeBrowserMainPartsPosix::PostMainMessageLoopRun();

#if !defined(OS_CHROMEOS)
  // Delete it now. Otherwise the FILE thread would be gone when we try to
  // release it in the dtor and Valgrind would report a leak on almost every
  // single browser_test.
  storage_monitor_.reset();
#endif
}
<|endoftext|>