<commit_before>/******************************************************************************
* Copyright (c) 2011, Howard Butler, hobu.inc@gmail.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/drivers/oci/Iterator.hpp>

#include <pdal/PointBuffer.hpp>
#include <pdal/drivers/oci/Reader.hpp>
#include <pdal/Vector.hpp>

#include <boost/algorithm/string.hpp>

#include <sstream>
#include <map>
#include <algorithm>

namespace pdal { namespace drivers { namespace oci {

IteratorBase::IteratorBase(const Reader& reader)
    : m_statement(Statement())
    , m_at_end(false)
    , m_cloud(reader.getCloud())
    , m_reader(reader)

{

    std::ostringstream select_blocks;

    select_blocks
        << "select T.OBJ_ID, T.BLK_ID, T.BLK_EXTENT, T.NUM_POINTS, T.POINTS from "
        << m_cloud->blk_table << " T WHERE T.OBJ_ID = "
        << m_cloud->pc_id;

    m_statement = Statement(m_cloud->connection->CreateStatement(select_blocks.str().c_str()));

    m_statement->Execute(0);
    m_block = defineBlock(m_statement);

    return;
}

IteratorBase::~IteratorBase()
{
}

const Reader& IteratorBase::getReader() const
{
    return m_reader;
}

void IteratorBase::read(PointBuffer& data,
                        boost::uint32_t howMany,
                        boost::uint32_t whichPoint,
                        boost::uint32_t whichBlobPosition)
{
    boost::uint32_t nAmountRead = 0;
    boost::uint32_t blob_length = m_statement->GetBlobLength(m_block->locator);

    if (m_block->chunk->size() < blob_length)
    {
        m_block->chunk->resize(blob_length);
    }

    // std::cout << "blob_length: " << blob_len// gth << std::endl;

    bool read_all_data = m_statement->ReadBlob( m_block->locator,
                                     (void*)(&(*m_block->chunk)[0]),
                                     m_block->chunk->size() ,
                                     &nAmountRead);
    if (!read_all_data) throw pdal_error("Did not read all blob data!");

    // std::cout << "nAmountRead: " << nAmountRead << std::endl;

    data.getSchema().getByteSize();
    boost::uint32_t howMuchToRead = howMany * data.getSchema().getByteSize();
    data.setDataStride(&(*m_block->chunk)[whichBlobPosition], whichPoint, howMuchToRead);

    data.setNumPoints(data.getNumPoints() + howMany);

}

boost::uint32_t IteratorBase::myReadBuffer(PointBuffer& data)
{
    boost::uint32_t numPointsRead = 0;

    data.setNumPoints(0);

    bool bDidRead = false;

    // std::cout << "m_block->num_points: " << m_block->num_points << std::endl;
    // std::cout << "data.getCapacity(): " << data.getCapacity() << std::endl;
    if (!m_block->num_points)
    {
        // We still have a block of data from the last readBuffer call
        // that was partially read.
        // std::cout << "reading because we have no points" << std::endl;
        bDidRead = m_statement->Fetch();
        if (!bDidRead)
        {
            m_at_end = true;
            return 0;
        }

        if (m_block->num_points > static_cast<boost::int32_t>(data.getCapacity()))
        {
            throw buffer_too_small("The PointBuffer is too small to contain this block.");
        }

    } else
    {
        // Our read was already "done" last readBuffer call, but if we're done,
        // we're done
        if (m_at_end) return 0;
        bDidRead = true;

    }

    while (bDidRead)
    {
        boost::uint32_t numReadThisBlock = m_block->num_points;
        boost::uint32_t numSpaceLeftThisBlock = data.getCapacity() - data.getNumPoints();

        if (numReadThisBlock > numSpaceLeftThisBlock)
        {
            // We're done.  We still have more data, but the
            // user is going to have to request another buffer.
            // We're not going to fill the buffer up to *exactly*
            // the number of points the user requested.
            // If the buffer's capacity isn't large enough to hold
            // an oracle block, they're just not going to get anything
            // back right now (FIXME)
            break;
        }

        numPointsRead = numPointsRead + numReadThisBlock;

        read(data, numReadThisBlock, data.getNumPoints(), 0);

        bDidRead = m_statement->Fetch();

        if (!bDidRead)
        {
            m_at_end = true;
            return numPointsRead;
        }
    }

    pdal::Vector<double> mins;
    pdal::Vector<double> maxs;

    boost::int32_t bounds_length = m_statement->GetArrayLength(&(m_block->blk_extent->sdo_ordinates));

    for (boost::int32_t i = 0; i < bounds_length; i = i + 2)
    {
        double v;
        m_statement->GetElement(&(m_block->blk_extent->sdo_ordinates), i, &v);
        mins.add(v);
        m_statement->GetElement(&(m_block->blk_extent->sdo_ordinates), i+1, &v);
        maxs.add(v);
    }

    pdal::Bounds<double> block_bounds(mins, maxs);

    data.setSpatialBounds(block_bounds);

    return numPointsRead;
}

//---------------------------------------------------------------------------
//
// SequentialIterator
//
//---------------------------------------------------------------------------

SequentialIterator::SequentialIterator(const Reader& reader)
    : IteratorBase(reader)
    , pdal::StageSequentialIterator(reader)
{
    return;
}

SequentialIterator::~SequentialIterator()
{
    return;
}

boost::uint64_t SequentialIterator::skipImpl(boost::uint64_t count)
{
    // const boost::uint64_t newPos64 = getIndex() + count;
    //
    // // The liblas reader's seek() call only supports size_t, so we might
    // // not be able to satisfy this request...
    //
    // if (newPos64 > std::numeric_limits<size_t>::max())
    // {
    //     throw pdal_error("cannot support seek offsets greater than 32-bits");
    // }
    //
    // // safe cast, since we just handled the overflow case
    // size_t newPos = static_cast<size_t>(newPos64);
    //
    // getExternalReader().Seek(newPos);

    return 0;
}

BlockPtr IteratorBase::defineBlock(Statement statement)
{

    int   iCol = 0;
    char  szFieldName[OWNAME];
    int   hType = 0;
    int   nSize = 0;
    int   nPrecision = 0;
    signed short nScale = 0;
    char szTypeName[OWNAME];

    BlockPtr block = BlockPtr(new Block(m_cloud->connection));

    m_cloud->connection->CreateType(&(block->blk_extent));

    while( statement->GetNextField(iCol, szFieldName, &hType, &nSize, &nPrecision, &nScale, szTypeName) )
    {
        std::string name = boost::to_upper_copy(std::string(szFieldName));

        if (boost::iequals(szFieldName, "OBJ_ID"))
        {
            statement->Define(&(block->obj_id));
        }

        if (boost::iequals(szFieldName, "BLK_ID"))
        {
            statement->Define(&(block->blk_id));
        }

        if (boost::iequals(szFieldName, "BLK_EXTENT"))
        {
            statement->Define(&(block->blk_extent));
        }

        if (boost::iequals(szFieldName, "BLK_DOMAIN"))
        {
            statement->Define(&(block->blk_domain));
        }

        if (boost::iequals(szFieldName, "PCBLK_MIN_RES"))
        {
            statement->Define(&(block->pcblk_min_res));
        }

        if (boost::iequals(szFieldName, "PCBLK_MAX_RES"))
        {
            statement->Define(&(block->pcblk_max_res));
        }

        if (boost::iequals(szFieldName, "NUM_POINTS"))
        {
            statement->Define(&(block->num_points));
        }

        if (boost::iequals(szFieldName, "NUM_UNSORTED_POINTS"))
        {
            statement->Define(&(block->num_unsorted_points));
        }

        if (boost::iequals(szFieldName, "PT_SORT_DIM"))
        {
            statement->Define(&(block->pt_sort_dim));
        }

        if (boost::iequals(szFieldName, "POINTS"))
        {
            statement->Define( &(block->locator) );
        }
        iCol++;
    }

    return block;
}

bool SequentialIterator::atEndImpl() const
{
    return m_at_end;
    // return getIndex() >= getStage().getNumPoints();
}

boost::uint32_t SequentialIterator::readBufferImpl(PointBuffer& data)
{
    return myReadBuffer(data);
}

//---------------------------------------------------------------------------
//
// RandomIterator
//
//---------------------------------------------------------------------------

} } } // namespaces
<commit_msg>decruft<commit_after>/******************************************************************************
* Copyright (c) 2011, Howard Butler, hobu.inc@gmail.com
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include <pdal/drivers/oci/Iterator.hpp>

#include <pdal/PointBuffer.hpp>
#include <pdal/drivers/oci/Reader.hpp>
#include <pdal/Vector.hpp>

#include <boost/algorithm/string.hpp>

#include <sstream>
#include <map>
#include <algorithm>

namespace pdal { namespace drivers { namespace oci {

IteratorBase::IteratorBase(const Reader& reader)
    : m_statement(Statement())
    , m_at_end(false)
    , m_cloud(reader.getCloud())
    , m_reader(reader)

{

    std::ostringstream select_blocks;

    select_blocks
        << "select T.OBJ_ID, T.BLK_ID, T.BLK_EXTENT, T.NUM_POINTS, T.POINTS from "
        << m_cloud->blk_table << " T WHERE T.OBJ_ID = "
        << m_cloud->pc_id;

    m_statement = Statement(m_cloud->connection->CreateStatement(select_blocks.str().c_str()));

    m_statement->Execute(0);
    m_block = defineBlock(m_statement);

    return;
}

IteratorBase::~IteratorBase()
{
}

const Reader& IteratorBase::getReader() const
{
    return m_reader;
}

void IteratorBase::read(PointBuffer& data,
                        boost::uint32_t howMany,
                        boost::uint32_t whichPoint,
                        boost::uint32_t whichBlobPosition)
{
    boost::uint32_t nAmountRead = 0;
    boost::uint32_t blob_length = m_statement->GetBlobLength(m_block->locator);

    if (m_block->chunk->size() < blob_length)
    {
        m_block->chunk->resize(blob_length);
    }

    // std::cout << "blob_length: " << blob_len// gth << std::endl;

    bool read_all_data = m_statement->ReadBlob( m_block->locator,
                                     (void*)(&(*m_block->chunk)[0]),
                                     m_block->chunk->size() ,
                                     &nAmountRead);
    if (!read_all_data) throw pdal_error("Did not read all blob data!");

    // std::cout << "nAmountRead: " << nAmountRead << std::endl;

    data.getSchema().getByteSize();
    boost::uint32_t howMuchToRead = howMany * data.getSchema().getByteSize();
    data.setDataStride(&(*m_block->chunk)[whichBlobPosition], whichPoint, howMuchToRead);

    data.setNumPoints(data.getNumPoints() + howMany);

}

boost::uint32_t IteratorBase::myReadBuffer(PointBuffer& data)
{
    boost::uint32_t numPointsRead = 0;

    data.setNumPoints(0);

    bool bDidRead = false;

    // std::cout << "m_block->num_points: " << m_block->num_points << std::endl;
    // std::cout << "data.getCapacity(): " << data.getCapacity() << std::endl;
    if (!m_block->num_points)
    {
        // We still have a block of data from the last readBuffer call
        // that was partially read.
        // std::cout << "reading because we have no points" << std::endl;
        bDidRead = m_statement->Fetch();
        if (!bDidRead)
        {
            m_at_end = true;
            return 0;
        }

        if (m_block->num_points > static_cast<boost::int32_t>(data.getCapacity()))
        {
            throw buffer_too_small("The PointBuffer is too small to contain this block.");
        }

    } else
    {
        // Our read was already "done" last readBuffer call, but if we're done,
        // we're done
        if (m_at_end) return 0;
        bDidRead = true;

    }

    while (bDidRead)
    {
        boost::uint32_t numReadThisBlock = m_block->num_points;
        boost::uint32_t numSpaceLeftThisBlock = data.getCapacity() - data.getNumPoints();

        if (numReadThisBlock > numSpaceLeftThisBlock)
        {
            // We're done.  We still have more data, but the
            // user is going to have to request another buffer.
            // We're not going to fill the buffer up to *exactly*
            // the number of points the user requested.
            // If the buffer's capacity isn't large enough to hold
            // an oracle block, they're just not going to get anything
            // back right now (FIXME)
            break;
        }

        numPointsRead = numPointsRead + numReadThisBlock;

        read(data, numReadThisBlock, data.getNumPoints(), 0);

        bDidRead = m_statement->Fetch();

        if (!bDidRead)
        {
            m_at_end = true;
            return numPointsRead;
        }
    }

    pdal::Vector<double> mins;
    pdal::Vector<double> maxs;

    boost::int32_t bounds_length = m_statement->GetArrayLength(&(m_block->blk_extent->sdo_ordinates));

    for (boost::int32_t i = 0; i < bounds_length; i = i + 2)
    {
        double v;
        m_statement->GetElement(&(m_block->blk_extent->sdo_ordinates), i, &v);
        mins.add(v);
        m_statement->GetElement(&(m_block->blk_extent->sdo_ordinates), i+1, &v);
        maxs.add(v);
    }

    pdal::Bounds<double> block_bounds(mins, maxs);

    data.setSpatialBounds(block_bounds);

    return numPointsRead;
}

//---------------------------------------------------------------------------
//
// SequentialIterator
//
//---------------------------------------------------------------------------

SequentialIterator::SequentialIterator(const Reader& reader)
    : IteratorBase(reader)
    , pdal::StageSequentialIterator(reader)
{
    return;
}

SequentialIterator::~SequentialIterator()
{
    return;
}

boost::uint64_t SequentialIterator::skipImpl(boost::uint64_t count)
{
    // const boost::uint64_t newPos64 = getIndex() + count;
    //
    // // The liblas reader's seek() call only supports size_t, so we might
    // // not be able to satisfy this request...
    //
    // if (newPos64 > std::numeric_limits<size_t>::max())
    // {
    //     throw pdal_error("cannot support seek offsets greater than 32-bits");
    // }
    //
    // // safe cast, since we just handled the overflow case
    // size_t newPos = static_cast<size_t>(newPos64);
    //
    // getExternalReader().Seek(newPos);

    return 0;
}

BlockPtr IteratorBase::defineBlock(Statement statement)
{

    int   iCol = 0;
    char  szFieldName[OWNAME];
    int   hType = 0;
    int   nSize = 0;
    int   nPrecision = 0;
    signed short nScale = 0;
    char szTypeName[OWNAME];

    BlockPtr block = BlockPtr(new Block(m_cloud->connection));

    m_cloud->connection->CreateType(&(block->blk_extent));

    while( statement->GetNextField(iCol, szFieldName, &hType, &nSize, &nPrecision, &nScale, szTypeName) )
    {
        std::string name = boost::to_upper_copy(std::string(szFieldName));

        if (boost::iequals(szFieldName, "OBJ_ID"))
        {
            statement->Define(&(block->obj_id));
        }

        if (boost::iequals(szFieldName, "BLK_ID"))
        {
            statement->Define(&(block->blk_id));
        }

        if (boost::iequals(szFieldName, "BLK_EXTENT"))
        {
            statement->Define(&(block->blk_extent));
        }

        if (boost::iequals(szFieldName, "BLK_DOMAIN"))
        {
            statement->Define(&(block->blk_domain));
        }

        if (boost::iequals(szFieldName, "PCBLK_MIN_RES"))
        {
            statement->Define(&(block->pcblk_min_res));
        }

        if (boost::iequals(szFieldName, "PCBLK_MAX_RES"))
        {
            statement->Define(&(block->pcblk_max_res));
        }

        if (boost::iequals(szFieldName, "NUM_POINTS"))
        {
            statement->Define(&(block->num_points));
        }

        if (boost::iequals(szFieldName, "NUM_UNSORTED_POINTS"))
        {
            statement->Define(&(block->num_unsorted_points));
        }

        if (boost::iequals(szFieldName, "PT_SORT_DIM"))
        {
            statement->Define(&(block->pt_sort_dim));
        }

        if (boost::iequals(szFieldName, "POINTS"))
        {
            statement->Define( &(block->locator) );
        }
        iCol++;
    }

    return block;
}

bool SequentialIterator::atEndImpl() const
{
    return m_at_end;
}

boost::uint32_t SequentialIterator::readBufferImpl(PointBuffer& data)
{
    return myReadBuffer(data);
}

//---------------------------------------------------------------------------
//
// RandomIterator
//
//---------------------------------------------------------------------------

} } } // namespaces
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrInOrderDrawBuffer.h"

// We will use the reordering buffer, unless we have NVPR.
// TODO move NVPR to batch so we can reorder
static inline bool allow_reordering(const GrCaps* caps) {
    return !caps->shaderCaps()->pathRenderingSupport();
}

GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context)
    : INHERITED(context)
    , fCommands(GrCommandBuilder::Create(context->getGpu(), allow_reordering(context->caps())))
    , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
    , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
    , fPipelineBuffer(kPipelineBufferMinReserve)
    , fDrawID(0) {
}

GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
    this->reset();
}

void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo);
    if (!state) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDrawBatch(state, batch);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
                                        const GrPathProcessor* pathProc,
                                        const GrPath* path,
                                        const GrScissorState& scissorState,
                                        const GrStencilSettings& stencilSettings) {
    GrTargetCommands::Cmd* cmd = fCommands->recordStencilPath(pipelineBuilder,
                                                              pathProc, path, scissorState,
                                                              stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
                                     const GrPath* path,
                                     const GrStencilSettings& stencilSettings,
                                     const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPath(state, pathProc, path, stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
                                      const GrPathRange* pathRange,
                                      const void* indices,
                                      PathIndexType indexType,
                                      const float transformValues[],
                                      PathTransformType transformType,
                                      int count,
                                      const GrStencilSettings& stencilSettings,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPaths(state, this, pathProc, pathRange,
                                                            indices, indexType, transformValues,
                                                            transformType, count,
                                                            stencilSettings, pipelineInfo);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
                                  bool canIgnoreRect, GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, canIgnoreRect, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
                                           bool insideClip,
                                           GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClearStencilClip(rect, insideClip, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
    if (!this->caps()->discardRenderTargetSupport()) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDiscard(renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onReset() {
    fCommands->reset();
    fPathIndexBuffer.rewind();
    fPathTransformBuffer.rewind();
    fGpuCmdMarkers.reset();

    fPrevState.reset(NULL);
    // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first.
    // Furthermore, we have to reset fCommands before fPipelineBuffer too.
    if (fDrawID % kPipelineBufferHighWaterMark) {
        fPipelineBuffer.rewind();
    } else {
        fPipelineBuffer.reset();
    }
}

void GrInOrderDrawBuffer::onFlush() {
    fCommands->flush(this);
    ++fDrawID;
}

void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
                                        GrSurface* src,
                                        const SkIRect& srcRect,
                                        const SkIPoint& dstPoint) {
    GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* cmd) {
    if (!cmd) {
        return;
    }
    const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
    if (activeTraceMarkers.count() > 0) {
        if (cmd->isTraced()) {
            fGpuCmdMarkers[cmd->markerID()].addSet(activeTraceMarkers);
        } else {
            cmd->setMarkerID(fGpuCmdMarkers.count());
            fGpuCmdMarkers.push_back(activeTraceMarkers);
        }
    }
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState(primProc);
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker,
                                                 state->getPipeline()->getInitBatchTracker());

    if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
                                                      *state->fPrimitiveProcessor,
                                                      state->fBatchTracker) &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState();
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    batch->initBatchTracker(state->getPipeline()->getInitBatchTracker());

    if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}
<commit_msg>fix dm crash<commit_after>/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "GrInOrderDrawBuffer.h"

// We will use the reordering buffer, unless we have NVPR.
// TODO move NVPR to batch so we can reorder
static inline bool allow_reordering(const GrCaps* caps) {
    return caps && caps->shaderCaps() && !caps->shaderCaps()->pathRenderingSupport();
}

GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context)
    : INHERITED(context)
    , fCommands(GrCommandBuilder::Create(context->getGpu(), allow_reordering(context->caps())))
    , fPathIndexBuffer(kPathIdxBufferMinReserve * sizeof(char)/4)
    , fPathTransformBuffer(kPathXformBufferMinReserve * sizeof(float)/4)
    , fPipelineBuffer(kPipelineBufferMinReserve)
    , fDrawID(0) {
}

GrInOrderDrawBuffer::~GrInOrderDrawBuffer() {
    this->reset();
}

void GrInOrderDrawBuffer::onDrawBatch(GrBatch* batch,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(batch, pipelineInfo);
    if (!state) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDrawBatch(state, batch);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onStencilPath(const GrPipelineBuilder& pipelineBuilder,
                                        const GrPathProcessor* pathProc,
                                        const GrPath* path,
                                        const GrScissorState& scissorState,
                                        const GrStencilSettings& stencilSettings) {
    GrTargetCommands::Cmd* cmd = fCommands->recordStencilPath(pipelineBuilder,
                                                              pathProc, path, scissorState,
                                                              stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPath(const GrPathProcessor* pathProc,
                                     const GrPath* path,
                                     const GrStencilSettings& stencilSettings,
                                     const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPath(state, pathProc, path, stencilSettings);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onDrawPaths(const GrPathProcessor* pathProc,
                                      const GrPathRange* pathRange,
                                      const void* indices,
                                      PathIndexType indexType,
                                      const float transformValues[],
                                      PathTransformType transformType,
                                      int count,
                                      const GrStencilSettings& stencilSettings,
                                      const PipelineInfo& pipelineInfo) {
    State* state = this->setupPipelineAndShouldDraw(pathProc, pipelineInfo);
    if (!state) {
        return;
    }
    GrTargetCommands::Cmd* cmd = fCommands->recordDrawPaths(state, this, pathProc, pathRange,
                                                            indices, indexType, transformValues,
                                                            transformType, count,
                                                            stencilSettings, pipelineInfo);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
                                  bool canIgnoreRect, GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClear(rect, color, canIgnoreRect, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
                                           bool insideClip,
                                           GrRenderTarget* renderTarget) {
    GrTargetCommands::Cmd* cmd = fCommands->recordClearStencilClip(rect, insideClip, renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::discard(GrRenderTarget* renderTarget) {
    if (!this->caps()->discardRenderTargetSupport()) {
        return;
    }

    GrTargetCommands::Cmd* cmd = fCommands->recordDiscard(renderTarget);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::onReset() {
    fCommands->reset();
    fPathIndexBuffer.rewind();
    fPathTransformBuffer.rewind();
    fGpuCmdMarkers.reset();

    fPrevState.reset(NULL);
    // Note, fPrevState points into fPipelineBuffer's allocation, so we have to reset first.
    // Furthermore, we have to reset fCommands before fPipelineBuffer too.
    if (fDrawID % kPipelineBufferHighWaterMark) {
        fPipelineBuffer.rewind();
    } else {
        fPipelineBuffer.reset();
    }
}

void GrInOrderDrawBuffer::onFlush() {
    fCommands->flush(this);
    ++fDrawID;
}

void GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
                                        GrSurface* src,
                                        const SkIRect& srcRect,
                                        const SkIPoint& dstPoint) {
    GrTargetCommands::Cmd* cmd = fCommands->recordCopySurface(dst, src, srcRect, dstPoint);
    this->recordTraceMarkersIfNecessary(cmd);
}

void GrInOrderDrawBuffer::recordTraceMarkersIfNecessary(GrTargetCommands::Cmd* cmd) {
    if (!cmd) {
        return;
    }
    const GrTraceMarkerSet& activeTraceMarkers = this->getActiveTraceMarkers();
    if (activeTraceMarkers.count() > 0) {
        if (cmd->isTraced()) {
            fGpuCmdMarkers[cmd->markerID()].addSet(activeTraceMarkers);
        } else {
            cmd->setMarkerID(fGpuCmdMarkers.count());
            fGpuCmdMarkers.push_back(activeTraceMarkers);
        }
    }
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(const GrPrimitiveProcessor* primProc,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState(primProc);
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    state->fPrimitiveProcessor->initBatchTracker(&state->fBatchTracker,
                                                 state->getPipeline()->getInitBatchTracker());

    if (fPrevState && fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->fPrimitiveProcessor->canMakeEqual(fPrevState->fBatchTracker,
                                                      *state->fPrimitiveProcessor,
                                                      state->fBatchTracker) &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}

GrTargetCommands::State*
GrInOrderDrawBuffer::setupPipelineAndShouldDraw(GrBatch* batch,
                                                const GrDrawTarget::PipelineInfo& pipelineInfo) {
    State* state = this->allocState();
    this->setupPipeline(pipelineInfo, state->pipelineLocation());

    if (state->getPipeline()->mustSkip()) {
        this->unallocState(state);
        return NULL;
    }

    batch->initBatchTracker(state->getPipeline()->getInitBatchTracker());

    if (fPrevState && !fPrevState->fPrimitiveProcessor.get() &&
        fPrevState->getPipeline()->isEqual(*state->getPipeline())) {
        this->unallocState(state);
    } else {
        fPrevState.reset(state);
    }

    this->recordTraceMarkersIfNecessary(
            fCommands->recordXferBarrierIfNecessary(*fPrevState->getPipeline(), *this->caps()));
    return fPrevState;
}
<|endoftext|>


<commit_before>#include "dialogrender.h"

#include <math.h>
#include <QVBoxLayout>
#include <QImage>
#include <QColor>
#include <QPainter>
#include <QMessageBox>
#include <QFileDialog>
#include <QMessageBox>
#include <QListWidget>
#include <QPushButton>
#include "tools.h"

#include "rendering/scenery.h"
#include "rendering/auto.h"

static DialogRender* _current_dialog;

static void _renderStart(int width, int height, Color background)
{
    _current_dialog->pixbuf_lock->lock();
    delete _current_dialog->pixbuf;
    _current_dialog->pixbuf = new QImage(width, height, QImage::Format_ARGB32);
    _current_dialog->pixbuf->fill(colorToQColor(background).rgb());
    _current_dialog->pixbuf_lock->unlock();

    _current_dialog->tellRenderSize(width, height);
}

static void _renderDraw(int x, int y, Color col)
{
    _current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
}

static void _renderUpdate(double progress)
{
    _current_dialog->area->update();
    _current_dialog->tellProgressChange(progress);
}

class RenderThread:public QThread
{
public:
    RenderThread(DialogRender* dialog, Renderer* renderer, RenderParams params):QThread()
    {
        _dialog = dialog;
        _renderer = renderer;
        _params = params;
    }
    void run()
    {
        rendererStart(_renderer, _params);
        _dialog->tellRenderEnded();
    }
private:
    DialogRender* _dialog;
    Renderer* _renderer;
    RenderParams _params;
};

class RenderArea:public QWidget
{
public:
    RenderArea(QWidget* parent):
        QWidget(parent)
    {
        setMinimumSize(800, 600);
    }

    void paintEvent(QPaintEvent*)
    {
        QPainter painter(this);
        _current_dialog->pixbuf_lock->lock();
        painter.drawImage(0, 0, *_current_dialog->pixbuf);
        _current_dialog->pixbuf_lock->unlock();
    }
};

DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
    QDialog(parent, Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint)
{
    pixbuf_lock = new QMutex();
    pixbuf = new QImage(1, 1, QImage::Format_ARGB32);
    _current_dialog = this;
    _render_thread = NULL;
    _renderer = renderer;

    setModal(true);
    setWindowTitle(tr("Paysages 3D - Render"));
    setLayout(new QVBoxLayout());

    _scroll = new QScrollArea(this);
    _scroll->setAlignment(Qt::AlignCenter);
    area = new RenderArea(_scroll);
    _scroll->setWidget(area);
    layout()->addWidget(_scroll);

    // Status bar
    _info = new QWidget(this);
    _info->setLayout(new QHBoxLayout());
    layout()->addWidget(_info);

    _timer = new QLabel(QString("0:00.00"), _info);
    _info->layout()->addWidget(_timer);

    _progress = new QProgressBar(_info);
    _progress->setMaximumHeight(12);
    _progress->setMinimum(0);
    _progress->setMaximum(1000);
    _progress->setValue(0);
    _info->layout()->addWidget(_progress);

    // Action bar
    _actions = new QWidget(this);
    _actions->setLayout(new QHBoxLayout());
    layout()->addWidget(_actions);

    _actions->layout()->addWidget(new QLabel(tr("Tone-mapping: "), _actions));
    _tonemapping_control = new QComboBox(_actions);
    _tonemapping_control->addItems(QStringList(tr("Uncharted")) << tr("Reinhard"));
    _actions->layout()->addWidget(_tonemapping_control);

    _actions->layout()->addWidget(new QLabel(tr("Exposure: "), _actions));
    _actions->hide();
    _exposure_control = new QSlider(Qt::Horizontal, _actions);
    _exposure_control->setMinimumWidth(200);
    _exposure_control->setRange(0, 1000);
    _exposure_control->setValue(200);
    _actions->layout()->addWidget(_exposure_control);

    _save_button = new QPushButton(QIcon(getDataPath("images/save.png")), tr("Save picture"), _actions);
    _actions->layout()->addWidget(_save_button);

    // Connections
    //connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int)));
    connect(this, SIGNAL(progressChanged(double)), this, SLOT(applyProgress(double)));
    connect(this, SIGNAL(renderEnded()), this, SLOT(applyRenderEnded()));
    connect(_save_button, SIGNAL(clicked()), this, SLOT(saveRender()));
    connect(_tonemapping_control, SIGNAL(currentIndexChanged(int)), this, SLOT(toneMappingChanged()));
    connect(_exposure_control, SIGNAL(valueChanged(int)), this, SLOT(toneMappingChanged()));
}

DialogRender::~DialogRender()
{
    if (_render_thread)
    {
        rendererInterrupt(_renderer);
        _render_thread->wait();

        delete _render_thread;
    }
    delete pixbuf;
    delete pixbuf_lock;
}

void DialogRender::tellRenderSize(int width, int height)
{
    emit renderSizeChanged(width, height);
}

void DialogRender::tellProgressChange(double value)
{
    emit progressChanged(value);
}

void DialogRender::tellRenderEnded()
{
    emit renderEnded();
}

void DialogRender::startRender(RenderParams params)
{
    _started = time(NULL);

    applyRenderSize(params.width, params.height);
    rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);

    _render_thread = new RenderThread(this, _renderer, params);
    _render_thread->start();

    exec();
}

void DialogRender::applyRenderEnded()
{
    _info->hide();
    _actions->show();
}

void DialogRender::saveRender()
{
    QString filepath;

    filepath = QFileDialog::getSaveFileName(this, tr("Paysages 3D - Choose a filename to save the last render"), QString(), tr("Images (*.png *.jpg)"));
    if (!filepath.isNull())
    {
        if (!filepath.toLower().endsWith(".jpg") && !filepath.toLower().endsWith(".jpeg") && !filepath.toLower().endsWith(".png"))
        {
            filepath = filepath.append(".png");
        }
        if (renderSaveToFile(_renderer->render_area, (char*)filepath.toStdString().c_str()))
        {
            QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
        }
        else
        {
            QMessageBox::critical(this, "Message", QString(tr("Can't write to file : %1")).arg(filepath));
        }
    }
}

void DialogRender::toneMappingChanged()
{
    renderSetToneMapping(_renderer->render_area, (ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01);
}

void DialogRender::loadLastRender()
{
    applyRenderSize(_renderer->render_width, _renderer->render_height);
    rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
    renderEnded();
    toneMappingChanged();

    exec();
}

void DialogRender::applyRenderSize(int width, int height)
{
    area->setMinimumSize(width, height);
    area->setMaximumSize(width, height);
    area->resize(width, height);
    _scroll->setMinimumSize(width > 800 ? 820 : width + 20, height > 600 ? 620 : height + 20);
}

void DialogRender::applyProgress(double value)
{
    double diff = difftime(time(NULL), _started);
    int hours = (int)floor(diff / 3600.0);
    int minutes = (int)floor((diff - 3600.0 * hours) / 60.0);
    int seconds = (int)floor(diff - 3600.0 * hours - 60.0 * minutes);
    _timer->setText(tr("%1:%2.%3").arg(hours).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
    _progress->setValue((int)(value * 1000.0));
    _progress->update();
}

<commit_msg>Partially fixed black widget after render.<commit_after>#include "dialogrender.h"

#include <math.h>
#include <QVBoxLayout>
#include <QImage>
#include <QColor>
#include <QPainter>
#include <QMessageBox>
#include <QFileDialog>
#include <QMessageBox>
#include <QListWidget>
#include <QPushButton>
#include "tools.h"

#include "rendering/scenery.h"
#include "rendering/auto.h"

static DialogRender* _current_dialog;

static void _renderStart(int width, int height, Color background)
{
    _current_dialog->pixbuf_lock->lock();
    delete _current_dialog->pixbuf;
    _current_dialog->pixbuf = new QImage(width, height, QImage::Format_ARGB32);
    _current_dialog->pixbuf->fill(colorToQColor(background).rgb());
    _current_dialog->pixbuf_lock->unlock();

    _current_dialog->tellRenderSize(width, height);
}

static void _renderDraw(int x, int y, Color col)
{
    _current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
}

static void _renderUpdate(double progress)
{
    _current_dialog->area->update();
    _current_dialog->tellProgressChange(progress);
}

class RenderThread:public QThread
{
public:
    RenderThread(DialogRender* dialog, Renderer* renderer, RenderParams params):QThread()
    {
        _dialog = dialog;
        _renderer = renderer;
        _params = params;
    }
    void run()
    {
        rendererStart(_renderer, _params);
        _dialog->tellRenderEnded();
    }
private:
    DialogRender* _dialog;
    Renderer* _renderer;
    RenderParams _params;
};

class RenderArea:public QWidget
{
public:
    RenderArea(QWidget* parent):
        QWidget(parent)
    {
        setMinimumSize(800, 600);
    }

    void paintEvent(QPaintEvent*)
    {
        QPainter painter(this);
        _current_dialog->pixbuf_lock->lock();
        painter.drawImage(0, 0, *_current_dialog->pixbuf);
        _current_dialog->pixbuf_lock->unlock();
    }
};

DialogRender::DialogRender(QWidget *parent, Renderer* renderer):
    QDialog(parent, Qt::WindowTitleHint | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint)
{
    pixbuf_lock = new QMutex();
    pixbuf = new QImage(1, 1, QImage::Format_ARGB32);
    _current_dialog = this;
    _render_thread = NULL;
    _renderer = renderer;

    setModal(true);
    setWindowTitle(tr("Paysages 3D - Render"));
    setLayout(new QVBoxLayout());

    _scroll = new QScrollArea(this);
    _scroll->setAlignment(Qt::AlignCenter);
    area = new RenderArea(_scroll);
    _scroll->setWidget(area);
    layout()->addWidget(_scroll);

    // Status bar
    _info = new QWidget(this);
    _info->setLayout(new QHBoxLayout());
    layout()->addWidget(_info);

    _timer = new QLabel(QString("0:00.00"), _info);
    _info->layout()->addWidget(_timer);

    _progress = new QProgressBar(_info);
    _progress->setMaximumHeight(12);
    _progress->setMinimum(0);
    _progress->setMaximum(1000);
    _progress->setValue(0);
    _info->layout()->addWidget(_progress);

    // Action bar
    _actions = new QWidget(this);
    _actions->setLayout(new QHBoxLayout());
    layout()->addWidget(_actions);

    _actions->layout()->addWidget(new QLabel(tr("Tone-mapping: "), _actions));
    _tonemapping_control = new QComboBox(_actions);
    _tonemapping_control->addItems(QStringList(tr("Uncharted")) << tr("Reinhard"));
    _actions->layout()->addWidget(_tonemapping_control);

    _actions->layout()->addWidget(new QLabel(tr("Exposure: "), _actions));
    _actions->hide();
    _exposure_control = new QSlider(Qt::Horizontal, _actions);
    _exposure_control->setMinimumWidth(200);
    _exposure_control->setRange(0, 1000);
    _exposure_control->setValue(200);
    _actions->layout()->addWidget(_exposure_control);

    _save_button = new QPushButton(QIcon(getDataPath("images/save.png")), tr("Save picture"), _actions);
    _actions->layout()->addWidget(_save_button);

    // Connections
    //connect(this, SIGNAL(renderSizeChanged(int, int)), this, SLOT(applyRenderSize(int, int)));
    connect(this, SIGNAL(progressChanged(double)), this, SLOT(applyProgress(double)));
    connect(this, SIGNAL(renderEnded()), this, SLOT(applyRenderEnded()));
    connect(_save_button, SIGNAL(clicked()), this, SLOT(saveRender()));
    connect(_tonemapping_control, SIGNAL(currentIndexChanged(int)), this, SLOT(toneMappingChanged()));
    connect(_exposure_control, SIGNAL(valueChanged(int)), this, SLOT(toneMappingChanged()));
}

DialogRender::~DialogRender()
{
    if (_render_thread)
    {
        rendererInterrupt(_renderer);
        _render_thread->wait();

        delete _render_thread;
    }
    delete pixbuf;
    delete pixbuf_lock;
}

void DialogRender::tellRenderSize(int width, int height)
{
    emit renderSizeChanged(width, height);
}

void DialogRender::tellProgressChange(double value)
{
    emit progressChanged(value);
}

void DialogRender::tellRenderEnded()
{
    emit renderEnded();
}

void DialogRender::startRender(RenderParams params)
{
    _started = time(NULL);

    applyRenderSize(params.width, params.height);
    rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);

    _render_thread = new RenderThread(this, _renderer, params);
    _render_thread->start();

    exec();
}

void DialogRender::applyRenderEnded()
{
    _info->hide();
    _actions->show();

    area->update();
}

void DialogRender::saveRender()
{
    QString filepath;

    filepath = QFileDialog::getSaveFileName(this, tr("Paysages 3D - Choose a filename to save the last render"), QString(), tr("Images (*.png *.jpg)"));
    if (!filepath.isNull())
    {
        if (!filepath.toLower().endsWith(".jpg") && !filepath.toLower().endsWith(".jpeg") && !filepath.toLower().endsWith(".png"))
        {
            filepath = filepath.append(".png");
        }
        if (renderSaveToFile(_renderer->render_area, (char*)filepath.toStdString().c_str()))
        {
            QMessageBox::information(this, "Message", QString(tr("The picture %1 has been saved.")).arg(filepath));
        }
        else
        {
            QMessageBox::critical(this, "Message", QString(tr("Can't write to file : %1")).arg(filepath));
        }
    }
}

void DialogRender::toneMappingChanged()
{
    renderSetToneMapping(_renderer->render_area, (ToneMappingOperator)_tonemapping_control->currentIndex(), ((double)_exposure_control->value()) * 0.01);
}

void DialogRender::loadLastRender()
{
    applyRenderSize(_renderer->render_width, _renderer->render_height);
    rendererSetPreviewCallbacks(_renderer, _renderStart, _renderDraw, _renderUpdate);
    renderEnded();
    toneMappingChanged();

    exec();
}

void DialogRender::applyRenderSize(int width, int height)
{
    area->setMinimumSize(width, height);
    area->setMaximumSize(width, height);
    area->resize(width, height);
    _scroll->setMinimumSize(width > 800 ? 820 : width + 20, height > 600 ? 620 : height + 20);
}

void DialogRender::applyProgress(double value)
{
    double diff = difftime(time(NULL), _started);
    int hours = (int)floor(diff / 3600.0);
    int minutes = (int)floor((diff - 3600.0 * hours) / 60.0);
    int seconds = (int)floor(diff - 3600.0 * hours - 60.0 * minutes);
    _timer->setText(tr("%1:%2.%3").arg(hours).arg(minutes, 2, 10, QLatin1Char('0')).arg(seconds, 2, 10, QLatin1Char('0')));
    _progress->setValue((int)(value * 1000.0));
    _progress->update();
}

<|endoftext|>


<commit_before>//=- llvm/CodeGen/DFAPacketizer.cpp - DFA Packetizer for VLIW -*- C++ -*-=====//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This class implements a deterministic finite automaton (DFA) based
// packetizing mechanism for VLIW architectures. It provides APIs to
// determine whether there exists a legal mapping of instructions to
// functional unit assignments in a packet. The DFA is auto-generated from
// the target's Schedule.td file.
//
// A DFA consists of 3 major elements: states, inputs, and transitions. For
// the packetizing mechanism, the input is the set of instruction classes for
// a target. The state models all possible combinations of functional unit
// consumption for a given set of instructions in a packet. A transition
// models the addition of an instruction to a packet. In the DFA constructed
// by this class, if an instruction can be added to a packet, then a valid
// transition exists from the corresponding state. Invalid transitions
// indicate that the instruction cannot be added to the current packet.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "packets"

#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Target/TargetInstrInfo.h"

using namespace llvm;

// --------------------------------------------------------------------
// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp

namespace {
  DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
    return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
  }

  /// Return the DFAInput for an instruction class input vector.
  /// This function is used in both DFAPacketizer.cpp and in
  /// DFAPacketizerEmitter.cpp.
  DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
    DFAInput InsnInput = 0;
    assert((InsnClass.size() <= DFA_MAX_RESTERMS) &&
           "Exceeded maximum number of DFA terms");
    for (auto U : InsnClass)
      InsnInput = addDFAFuncUnits(InsnInput, U);
    return InsnInput;
  }
}
// --------------------------------------------------------------------

DFAPacketizer::DFAPacketizer(const InstrItineraryData *I,
                             const DFAStateInput (*SIT)[2],
                             const unsigned *SET):
  InstrItins(I), CurrentState(0), DFAStateInputTable(SIT),
  DFAStateEntryTable(SET) {
  // Make sure DFA types are large enough for the number of terms & resources.
  static_assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <=
                    (8 * sizeof(DFAInput)),
                "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAInput");
  static_assert(
      (DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAStateInput)),
      "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAStateInput");
}

// Read the DFA transition table and update CachedTable.
//
// Format of the transition tables:
// DFAStateInputTable[][2] = pairs of <Input, Transition> for all valid
//                           transitions
// DFAStateEntryTable[i] = Index of the first entry in DFAStateInputTable
//                         for the ith state
//
void DFAPacketizer::ReadTable(unsigned int state) {
  unsigned ThisState = DFAStateEntryTable[state];
  unsigned NextStateInTable = DFAStateEntryTable[state+1];
  // Early exit in case CachedTable has already contains this
  // state's transitions.
  if (CachedTable.count(UnsignPair(state, DFAStateInputTable[ThisState][0])))
    return;

  for (unsigned i = ThisState; i < NextStateInTable; i++)
    CachedTable[UnsignPair(state, DFAStateInputTable[i][0])] =
      DFAStateInputTable[i][1];
}

// Return the DFAInput for an instruction class.
DFAInput DFAPacketizer::getInsnInput(unsigned InsnClass) {
  // Note: this logic must match that in DFAPacketizerDefs.h for input vectors.
  DFAInput InsnInput = 0;
  unsigned i = 0;
  (void)i;
  for (const InstrStage *IS = InstrItins->beginStage(InsnClass),
       *IE = InstrItins->endStage(InsnClass); IS != IE; ++IS) {
    InsnInput = addDFAFuncUnits(InsnInput, IS->getUnits());
    assert((i++ < DFA_MAX_RESTERMS) && "Exceeded maximum number of DFA inputs");
  }
  return InsnInput;
}

// Return the DFAInput for an instruction class input vector.
DFAInput DFAPacketizer::getInsnInput(const std::vector<unsigned> &InsnClass) {
  return getDFAInsnInput(InsnClass);
}

// Check if the resources occupied by a MCInstrDesc are available in the
// current state.
bool DFAPacketizer::canReserveResources(const llvm::MCInstrDesc *MID) {
  unsigned InsnClass = MID->getSchedClass();
  DFAInput InsnInput = getInsnInput(InsnClass);
  UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
  ReadTable(CurrentState);
  return CachedTable.count(StateTrans) != 0;
}

// Reserve the resources occupied by a MCInstrDesc and change the current
// state to reflect that change.
void DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
  unsigned InsnClass = MID->getSchedClass();
  DFAInput InsnInput = getInsnInput(InsnClass);
  UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
  ReadTable(CurrentState);
  assert(CachedTable.count(StateTrans) != 0);
  CurrentState = CachedTable[StateTrans];
}

// Check if the resources occupied by a machine instruction are available
// in the current state.
bool DFAPacketizer::canReserveResources(llvm::MachineInstr &MI) {
  const llvm::MCInstrDesc &MID = MI.getDesc();
  return canReserveResources(&MID);
}

// Reserve the resources occupied by a machine instruction and change the
// current state to reflect that change.
void DFAPacketizer::reserveResources(llvm::MachineInstr &MI) {
  const llvm::MCInstrDesc &MID = MI.getDesc();
  reserveResources(&MID);
}

namespace llvm {
// This class extends ScheduleDAGInstrs and overrides the schedule method
// to build the dependence graph.
class DefaultVLIWScheduler : public ScheduleDAGInstrs {
private:
  AliasAnalysis *AA;
  /// Ordered list of DAG postprocessing steps.
  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
public:
  DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
                       AliasAnalysis *AA);
  // Actual scheduling work.
  void schedule() override;

  /// DefaultVLIWScheduler takes ownership of the Mutation object.
  void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
    Mutations.push_back(std::move(Mutation));
  }
protected:
  void postprocessDAG();
};
}

DefaultVLIWScheduler::DefaultVLIWScheduler(MachineFunction &MF,
                                           MachineLoopInfo &MLI,
                                           AliasAnalysis *AA)
    : ScheduleDAGInstrs(MF, &MLI), AA(AA) {
  CanHandleTerminators = true;
}

/// Apply each ScheduleDAGMutation step in order.
void DefaultVLIWScheduler::postprocessDAG() {
  for (auto &M : Mutations)
    M->apply(this);
}

void DefaultVLIWScheduler::schedule() {
  // Build the scheduling graph.
  buildSchedGraph(AA);
  postprocessDAG();
}

VLIWPacketizerList::VLIWPacketizerList(MachineFunction &mf,
                                       MachineLoopInfo &mli, AliasAnalysis *aa)
    : MF(mf), TII(mf.getSubtarget().getInstrInfo()), AA(aa) {
  ResourceTracker = TII->CreateTargetScheduleState(MF.getSubtarget());
  VLIWScheduler = new DefaultVLIWScheduler(MF, mli, AA);
}

VLIWPacketizerList::~VLIWPacketizerList() {
  if (VLIWScheduler)
    delete VLIWScheduler;
  if (ResourceTracker)
    delete ResourceTracker;
}

// End the current packet, bundle packet instructions and reset DFA state.
void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
                                   MachineBasicBlock::iterator MI) {
  if (CurrentPacketMIs.size() > 1) {
    MachineInstr &MIFirst = *CurrentPacketMIs.front();
    finalizeBundle(*MBB, MIFirst.getIterator(), MI.getInstrIterator());
  }
  CurrentPacketMIs.clear();
  ResourceTracker->clearResources();
  DEBUG(dbgs() << "End packet\n");
}

// Bundle machine instructions into packets.
void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
                                      MachineBasicBlock::iterator BeginItr,
                                      MachineBasicBlock::iterator EndItr) {
  assert(VLIWScheduler && "VLIW Scheduler is not initialized!");
  VLIWScheduler->startBlock(MBB);
  VLIWScheduler->enterRegion(MBB, BeginItr, EndItr,
                             std::distance(BeginItr, EndItr));
  VLIWScheduler->schedule();

  DEBUG({
    dbgs() << "Scheduling DAG of the packetize region\n";
    for (SUnit &SU : VLIWScheduler->SUnits)
      SU.dumpAll(VLIWScheduler);
  });

  // Generate MI -> SU map.
  MIToSUnit.clear();
  for (SUnit &SU : VLIWScheduler->SUnits)
    MIToSUnit[SU.getInstr()] = &SU;

  // The main packetizer loop.
  for (; BeginItr != EndItr; ++BeginItr) {
    MachineInstr &MI = *BeginItr;
    initPacketizerState();

    // End the current packet if needed.
    if (isSoloInstruction(MI)) {
      endPacket(MBB, MI);
      continue;
    }

    // Ignore pseudo instructions.
    if (ignorePseudoInstruction(MI, MBB))
      continue;

    SUnit *SUI = MIToSUnit[&MI];
    assert(SUI && "Missing SUnit Info!");

    // Ask DFA if machine resource is available for MI.
    DEBUG(dbgs() << "Checking resources for adding MI to packet " << MI);

    bool ResourceAvail = ResourceTracker->canReserveResources(MI);
    DEBUG({
      if (ResourceAvail)
        dbgs() << "  Resources are available for adding MI to packet\n";
      else
        dbgs() << "  Resources NOT available\n";
    });
    if (ResourceAvail && shouldAddToPacket(MI)) {
      // Dependency check for MI with instructions in CurrentPacketMIs.
      for (auto MJ : CurrentPacketMIs) {
        SUnit *SUJ = MIToSUnit[MJ];
        assert(SUJ && "Missing SUnit Info!");

        DEBUG(dbgs() << "  Checking against MJ " << *MJ);
        // Is it legal to packetize SUI and SUJ together.
        if (!isLegalToPacketizeTogether(SUI, SUJ)) {
          DEBUG(dbgs() << "  Not legal to add MI, try to prune\n");
          // Allow packetization if dependency can be pruned.
          if (!isLegalToPruneDependencies(SUI, SUJ)) {
            // End the packet if dependency cannot be pruned.
            DEBUG(dbgs() << "  Could not prune dependencies for adding MI\n");
            endPacket(MBB, MI);
            break;
          }
          DEBUG(dbgs() << "  Pruned dependence for adding MI\n");
        }
      }
    } else {
      DEBUG(if (ResourceAvail)
        dbgs() << "Resources are available, but instruction should not be "
                  "added to packet\n  " << MI);
      // End the packet if resource is not available, or if the instruction
      // shoud not be added to the current packet.
      endPacket(MBB, MI);
    }

    // Add MI to the current packet.
    DEBUG(dbgs() << "* Adding MI to packet " << MI << '\n');
    BeginItr = addToPacket(MI);
  } // For all instructions in the packetization range.

  // End any packet left behind.
  endPacket(MBB, EndItr);
  VLIWScheduler->exitRegion();
  VLIWScheduler->finishBlock();
}

// Add a DAG mutation object to the ordered list.
void VLIWPacketizerList::addMutation(
      std::unique_ptr<ScheduleDAGMutation> Mutation) {
  VLIWScheduler->addMutation(std::move(Mutation));
}
<commit_msg>[Packetizer] Add debugging code to stop packetization after N instructions<commit_after>//=- llvm/CodeGen/DFAPacketizer.cpp - DFA Packetizer for VLIW -*- C++ -*-=====//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This class implements a deterministic finite automaton (DFA) based
// packetizing mechanism for VLIW architectures. It provides APIs to
// determine whether there exists a legal mapping of instructions to
// functional unit assignments in a packet. The DFA is auto-generated from
// the target's Schedule.td file.
//
// A DFA consists of 3 major elements: states, inputs, and transitions. For
// the packetizing mechanism, the input is the set of instruction classes for
// a target. The state models all possible combinations of functional unit
// consumption for a given set of instructions in a packet. A transition
// models the addition of an instruction to a packet. In the DFA constructed
// by this class, if an instruction can be added to a packet, then a valid
// transition exists from the corresponding state. Invalid transitions
// indicate that the instruction cannot be added to the current packet.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "packets"

#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/CommandLine.h"

using namespace llvm;

static cl::opt<unsigned> InstrLimit("dfa-instr-limit", cl::Hidden,
  cl::init(0), cl::desc("If present, stops packetizing after N instructions"));
static unsigned InstrCount = 0;

// --------------------------------------------------------------------
// Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp

namespace {
  DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
    return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
  }

  /// Return the DFAInput for an instruction class input vector.
  /// This function is used in both DFAPacketizer.cpp and in
  /// DFAPacketizerEmitter.cpp.
  DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
    DFAInput InsnInput = 0;
    assert((InsnClass.size() <= DFA_MAX_RESTERMS) &&
           "Exceeded maximum number of DFA terms");
    for (auto U : InsnClass)
      InsnInput = addDFAFuncUnits(InsnInput, U);
    return InsnInput;
  }
}
// --------------------------------------------------------------------

DFAPacketizer::DFAPacketizer(const InstrItineraryData *I,
                             const DFAStateInput (*SIT)[2],
                             const unsigned *SET):
  InstrItins(I), CurrentState(0), DFAStateInputTable(SIT),
  DFAStateEntryTable(SET) {
  // Make sure DFA types are large enough for the number of terms & resources.
  static_assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <=
                    (8 * sizeof(DFAInput)),
                "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAInput");
  static_assert(
      (DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAStateInput)),
      "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAStateInput");
}

// Read the DFA transition table and update CachedTable.
//
// Format of the transition tables:
// DFAStateInputTable[][2] = pairs of <Input, Transition> for all valid
//                           transitions
// DFAStateEntryTable[i] = Index of the first entry in DFAStateInputTable
//                         for the ith state
//
void DFAPacketizer::ReadTable(unsigned int state) {
  unsigned ThisState = DFAStateEntryTable[state];
  unsigned NextStateInTable = DFAStateEntryTable[state+1];
  // Early exit in case CachedTable has already contains this
  // state's transitions.
  if (CachedTable.count(UnsignPair(state, DFAStateInputTable[ThisState][0])))
    return;

  for (unsigned i = ThisState; i < NextStateInTable; i++)
    CachedTable[UnsignPair(state, DFAStateInputTable[i][0])] =
      DFAStateInputTable[i][1];
}

// Return the DFAInput for an instruction class.
DFAInput DFAPacketizer::getInsnInput(unsigned InsnClass) {
  // Note: this logic must match that in DFAPacketizerDefs.h for input vectors.
  DFAInput InsnInput = 0;
  unsigned i = 0;
  (void)i;
  for (const InstrStage *IS = InstrItins->beginStage(InsnClass),
       *IE = InstrItins->endStage(InsnClass); IS != IE; ++IS) {
    InsnInput = addDFAFuncUnits(InsnInput, IS->getUnits());
    assert((i++ < DFA_MAX_RESTERMS) && "Exceeded maximum number of DFA inputs");
  }
  return InsnInput;
}

// Return the DFAInput for an instruction class input vector.
DFAInput DFAPacketizer::getInsnInput(const std::vector<unsigned> &InsnClass) {
  return getDFAInsnInput(InsnClass);
}

// Check if the resources occupied by a MCInstrDesc are available in the
// current state.
bool DFAPacketizer::canReserveResources(const llvm::MCInstrDesc *MID) {
  unsigned InsnClass = MID->getSchedClass();
  DFAInput InsnInput = getInsnInput(InsnClass);
  UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
  ReadTable(CurrentState);
  return CachedTable.count(StateTrans) != 0;
}

// Reserve the resources occupied by a MCInstrDesc and change the current
// state to reflect that change.
void DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
  unsigned InsnClass = MID->getSchedClass();
  DFAInput InsnInput = getInsnInput(InsnClass);
  UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
  ReadTable(CurrentState);
  assert(CachedTable.count(StateTrans) != 0);
  CurrentState = CachedTable[StateTrans];
}

// Check if the resources occupied by a machine instruction are available
// in the current state.
bool DFAPacketizer::canReserveResources(llvm::MachineInstr &MI) {
  const llvm::MCInstrDesc &MID = MI.getDesc();
  return canReserveResources(&MID);
}

// Reserve the resources occupied by a machine instruction and change the
// current state to reflect that change.
void DFAPacketizer::reserveResources(llvm::MachineInstr &MI) {
  const llvm::MCInstrDesc &MID = MI.getDesc();
  reserveResources(&MID);
}

namespace llvm {
// This class extends ScheduleDAGInstrs and overrides the schedule method
// to build the dependence graph.
class DefaultVLIWScheduler : public ScheduleDAGInstrs {
private:
  AliasAnalysis *AA;
  /// Ordered list of DAG postprocessing steps.
  std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
public:
  DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
                       AliasAnalysis *AA);
  // Actual scheduling work.
  void schedule() override;

  /// DefaultVLIWScheduler takes ownership of the Mutation object.
  void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
    Mutations.push_back(std::move(Mutation));
  }
protected:
  void postprocessDAG();
};
}

DefaultVLIWScheduler::DefaultVLIWScheduler(MachineFunction &MF,
                                           MachineLoopInfo &MLI,
                                           AliasAnalysis *AA)
    : ScheduleDAGInstrs(MF, &MLI), AA(AA) {
  CanHandleTerminators = true;
}

/// Apply each ScheduleDAGMutation step in order.
void DefaultVLIWScheduler::postprocessDAG() {
  for (auto &M : Mutations)
    M->apply(this);
}

void DefaultVLIWScheduler::schedule() {
  // Build the scheduling graph.
  buildSchedGraph(AA);
  postprocessDAG();
}

VLIWPacketizerList::VLIWPacketizerList(MachineFunction &mf,
                                       MachineLoopInfo &mli, AliasAnalysis *aa)
    : MF(mf), TII(mf.getSubtarget().getInstrInfo()), AA(aa) {
  ResourceTracker = TII->CreateTargetScheduleState(MF.getSubtarget());
  VLIWScheduler = new DefaultVLIWScheduler(MF, mli, AA);
}

VLIWPacketizerList::~VLIWPacketizerList() {
  if (VLIWScheduler)
    delete VLIWScheduler;
  if (ResourceTracker)
    delete ResourceTracker;
}

// End the current packet, bundle packet instructions and reset DFA state.
void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
                                   MachineBasicBlock::iterator MI) {
  DEBUG({
    if (!CurrentPacketMIs.empty()) {
      dbgs() << "Finalizing packet:\n";
      for (MachineInstr *MI : CurrentPacketMIs)
        dbgs() << " * " << *MI;
    }
  });
  if (CurrentPacketMIs.size() > 1) {
    MachineInstr &MIFirst = *CurrentPacketMIs.front();
    finalizeBundle(*MBB, MIFirst.getIterator(), MI.getInstrIterator());
  }
  CurrentPacketMIs.clear();
  ResourceTracker->clearResources();
  DEBUG(dbgs() << "End packet\n");
}

// Bundle machine instructions into packets.
void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
                                      MachineBasicBlock::iterator BeginItr,
                                      MachineBasicBlock::iterator EndItr) {
  assert(VLIWScheduler && "VLIW Scheduler is not initialized!");
  VLIWScheduler->startBlock(MBB);
  VLIWScheduler->enterRegion(MBB, BeginItr, EndItr,
                             std::distance(BeginItr, EndItr));
  VLIWScheduler->schedule();

  DEBUG({
    dbgs() << "Scheduling DAG of the packetize region\n";
    for (SUnit &SU : VLIWScheduler->SUnits)
      SU.dumpAll(VLIWScheduler);
  });

  // Generate MI -> SU map.
  MIToSUnit.clear();
  for (SUnit &SU : VLIWScheduler->SUnits)
    MIToSUnit[SU.getInstr()] = &SU;

  bool LimitPresent = InstrLimit.getPosition();

  // The main packetizer loop.
  for (; BeginItr != EndItr; ++BeginItr) {
    if (LimitPresent) {
      if (InstrCount >= InstrLimit) {
        EndItr = BeginItr;
        break;
      }
      InstrCount++;
    }
    MachineInstr &MI = *BeginItr;
    initPacketizerState();

    // End the current packet if needed.
    if (isSoloInstruction(MI)) {
      endPacket(MBB, MI);
      continue;
    }

    // Ignore pseudo instructions.
    if (ignorePseudoInstruction(MI, MBB))
      continue;

    SUnit *SUI = MIToSUnit[&MI];
    assert(SUI && "Missing SUnit Info!");

    // Ask DFA if machine resource is available for MI.
    DEBUG(dbgs() << "Checking resources for adding MI to packet " << MI);

    bool ResourceAvail = ResourceTracker->canReserveResources(MI);
    DEBUG({
      if (ResourceAvail)
        dbgs() << "  Resources are available for adding MI to packet\n";
      else
        dbgs() << "  Resources NOT available\n";
    });
    if (ResourceAvail && shouldAddToPacket(MI)) {
      // Dependency check for MI with instructions in CurrentPacketMIs.
      for (auto MJ : CurrentPacketMIs) {
        SUnit *SUJ = MIToSUnit[MJ];
        assert(SUJ && "Missing SUnit Info!");

        DEBUG(dbgs() << "  Checking against MJ " << *MJ);
        // Is it legal to packetize SUI and SUJ together.
        if (!isLegalToPacketizeTogether(SUI, SUJ)) {
          DEBUG(dbgs() << "  Not legal to add MI, try to prune\n");
          // Allow packetization if dependency can be pruned.
          if (!isLegalToPruneDependencies(SUI, SUJ)) {
            // End the packet if dependency cannot be pruned.
            DEBUG(dbgs() << "  Could not prune dependencies for adding MI\n");
            endPacket(MBB, MI);
            break;
          }
          DEBUG(dbgs() << "  Pruned dependence for adding MI\n");
        }
      }
    } else {
      DEBUG(if (ResourceAvail)
        dbgs() << "Resources are available, but instruction should not be "
                  "added to packet\n  " << MI);
      // End the packet if resource is not available, or if the instruction
      // shoud not be added to the current packet.
      endPacket(MBB, MI);
    }

    // Add MI to the current packet.
    DEBUG(dbgs() << "* Adding MI to packet " << MI << '\n');
    BeginItr = addToPacket(MI);
  } // For all instructions in the packetization range.

  // End any packet left behind.
  endPacket(MBB, EndItr);
  VLIWScheduler->exitRegion();
  VLIWScheduler->finishBlock();
}

// Add a DAG mutation object to the ordered list.
void VLIWPacketizerList::addMutation(
      std::unique_ptr<ScheduleDAGMutation> Mutation) {
  VLIWScheduler->addMutation(std::move(Mutation));
}
<|endoftext|>


<commit_before>//
//  http_client_handler_file.cc
//

#include "plat_os.h"
#include "plat_net.h"

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cerrno>
#include <csignal>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <deque>
#include <map>
#include <atomic>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>

#include "io.h"
#include "url.h"
#include "log.h"
#include "socket.h"
#include "socket_unix.h"
#include "resolver.h"
#include "config_parser.h"
#include "config.h"
#include "pollset.h"
#include "protocol.h"
#include "connection.h"
#include "connection.h"
#include "protocol_thread.h"
#include "protocol_engine.h"
#include "protocol_connection.h"

#include "http_common.h"
#include "http_constants.h"
#include "http_parser.h"
#include "http_request.h"
#include "http_response.h"
#include "http_date.h"
#include "http_client.h"
#include "http_client_handler_file.h"

/* http_client_handler_file */

http_client_handler_file::http_client_handler_file() : file_resource(-1) {}

http_client_handler_file::http_client_handler_file(int fd) : file_resource(fd) {}

http_client_handler_file::~http_client_handler_file() {}

void http_client_handler_file::init()
{
    http_version = HTTPVersion11;
    status_code = HTTPStatusCodeNone;
    request_method = HTTPMethodNone;
    content_length = -1;
    total_read = 0;
}

bool http_client_handler_file::populate_request()
{
    // get request http version and request method
    http_version = http_constants::get_version_type(http_conn->request.get_http_version());
    request_method = http_constants::get_method_type(http_conn->request.get_request_method());

    // set request/response body
    switch (request_method) {
        case HTTPMethodPOST:
            http_conn->request_has_body = true;
            http_conn->response_has_body = true;
            break;
        case HTTPMethodHEAD:
            http_conn->request_has_body = false;
            http_conn->response_has_body = false;
            break;
        case HTTPMethodGET:
        default:
            http_conn->request_has_body = false;
            http_conn->response_has_body = true;
            break;
    }

    // TODO - add any additional request headers

    return true;
}

io_result http_client_handler_file::write_request_body()
{
    return io_result(0);
}

bool http_client_handler_file::handle_response()
{
    // set connection close
    http_version = http_constants::get_version_type(http_conn->response.get_http_version());
    status_code =(HTTPStatusCode)http_conn->response.get_status_code();
    const char* connection_str = http_conn->response.get_header_string(kHTTPHeaderConnection);
    bool connection_keepalive_present = (connection_str && strcasecmp(connection_str, kHTTPTokenKeepalive) == 0);
    bool connection_close_present = (connection_str && strcasecmp(connection_str, kHTTPTokenClose) == 0);
    switch (http_version) {
        case HTTPVersion10:
            http_conn->connection_close = !connection_keepalive_present;
            break;
        case HTTPVersion11:
            http_conn->connection_close = connection_close_present;
            break;
        default:
            http_conn->connection_close = true;
            break;
    }

    // get content length
    const char* content_length_str = http_conn->response.get_header_string(kHTTPHeaderContentLength);
    content_length = content_length_str ? strtoll(content_length_str, NULL, 10) : -1;
    total_read = 0;

    return true;
}

io_result http_client_handler_file::read_response_body()
{
    auto &buffer = http_conn->buffer;

    // handle body fragment in the buffer
    if (buffer.bytes_readable() > 0) {
        ssize_t bytes_readable = buffer.bytes_readable();
        if (file_resource.get_fd() >= 0) {
            io_result result = buffer.buffer_write(file_resource);
            if (result.has_error()) {
                log_error("http_client_handler_file: write: %s", strerror(result.error().errcode));
            } else if (result.size() != bytes_readable) {
                log_error("http_client_handler_file: short_write");
            }
        }
        total_read += bytes_readable;
        buffer.reset();
        return io_result(-1);
    }

    if (total_read == content_length) return io_result(0);

    // read data from socket
    io_result result = buffer.buffer_read(http_conn->conn);
    if (result.has_error()) {
        return io_result(io_error(errno));
    } else if (buffer.bytes_readable() > 0) {
        ssize_t bytes_readable = buffer.bytes_readable();
        if (file_resource.get_fd() >= 0) {
            io_result result = buffer.buffer_write(file_resource);
            if (result.has_error()) {
                log_error("http_client_handler_file: write: %s", strerror(result.error().errcode));
            } else if (result.size() != bytes_readable) {
                log_error("http_client_handler_file: short_write");
            }
        }
        total_read += bytes_readable;
        buffer.reset();
    }

    // return bytes available or -1 if content length not present
    if (content_length >= 0) {
        return io_result(content_length - total_read);
    } else {
        return io_result(-1);
    }
}

bool http_client_handler_file::end_request()
{
    return true;
}
<commit_msg>Fix handling of residual buffer in read_response_body<commit_after>//
//  http_client_handler_file.cc
//

#include "plat_os.h"
#include "plat_net.h"

#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cerrno>
#include <csignal>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <deque>
#include <map>
#include <atomic>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>

#include "io.h"
#include "url.h"
#include "log.h"
#include "socket.h"
#include "socket_unix.h"
#include "resolver.h"
#include "config_parser.h"
#include "config.h"
#include "pollset.h"
#include "protocol.h"
#include "connection.h"
#include "connection.h"
#include "protocol_thread.h"
#include "protocol_engine.h"
#include "protocol_connection.h"

#include "http_common.h"
#include "http_constants.h"
#include "http_parser.h"
#include "http_request.h"
#include "http_response.h"
#include "http_date.h"
#include "http_client.h"
#include "http_client_handler_file.h"

/* http_client_handler_file */

http_client_handler_file::http_client_handler_file() : file_resource(-1) {}

http_client_handler_file::http_client_handler_file(int fd) : file_resource(fd) {}

http_client_handler_file::~http_client_handler_file() {}

void http_client_handler_file::init()
{
    http_version = HTTPVersion11;
    status_code = HTTPStatusCodeNone;
    request_method = HTTPMethodNone;
    content_length = -1;
    total_read = 0;
}

bool http_client_handler_file::populate_request()
{
    // get request http version and request method
    http_version = http_constants::get_version_type(http_conn->request.get_http_version());
    request_method = http_constants::get_method_type(http_conn->request.get_request_method());

    // set request/response body
    switch (request_method) {
        case HTTPMethodPOST:
            http_conn->request_has_body = true;
            http_conn->response_has_body = true;
            break;
        case HTTPMethodHEAD:
            http_conn->request_has_body = false;
            http_conn->response_has_body = false;
            break;
        case HTTPMethodGET:
        default:
            http_conn->request_has_body = false;
            http_conn->response_has_body = true;
            break;
    }

    // TODO - add any additional request headers

    return true;
}

io_result http_client_handler_file::write_request_body()
{
    return io_result(0);
}

bool http_client_handler_file::handle_response()
{
    // set connection close
    http_version = http_constants::get_version_type(http_conn->response.get_http_version());
    status_code =(HTTPStatusCode)http_conn->response.get_status_code();
    const char* connection_str = http_conn->response.get_header_string(kHTTPHeaderConnection);
    bool connection_keepalive_present = (connection_str && strcasecmp(connection_str, kHTTPTokenKeepalive) == 0);
    bool connection_close_present = (connection_str && strcasecmp(connection_str, kHTTPTokenClose) == 0);
    switch (http_version) {
        case HTTPVersion10:
            http_conn->connection_close = !connection_keepalive_present;
            break;
        case HTTPVersion11:
            http_conn->connection_close = connection_close_present;
            break;
        default:
            http_conn->connection_close = true;
            break;
    }

    // get content length
    const char* content_length_str = http_conn->response.get_header_string(kHTTPHeaderContentLength);
    content_length = content_length_str ? strtoll(content_length_str, NULL, 10) : -1;
    total_read = 0;

    return true;
}

io_result http_client_handler_file::read_response_body()
{
    auto &buffer = http_conn->buffer;

    // handle body fragment in the buffer
    if (buffer.bytes_readable() > 0) {
        ssize_t bytes_readable = buffer.bytes_readable();
        if (file_resource.get_fd() >= 0) {
            io_result result = buffer.buffer_write(file_resource);
            if (result.has_error()) {
                log_error("http_client_handler_file: write: %s", strerror(result.error().errcode));
            } else if (result.size() != bytes_readable) {
                log_error("http_client_handler_file: short_write");
            }
        }
        total_read += bytes_readable;
        buffer.reset();

        // return bytes available or -1 if content length not present
        if (content_length >= 0) {
            return io_result(content_length - total_read);
        } else {
            return io_result(-1);
        }
    }

    if (total_read == content_length) return io_result(0);

    // read data from socket
    io_result result = buffer.buffer_read(http_conn->conn);
    if (result.has_error()) {
        return io_result(io_error(errno));
    } else if (buffer.bytes_readable() > 0) {
        ssize_t bytes_readable = buffer.bytes_readable();
        if (file_resource.get_fd() >= 0) {
            io_result result = buffer.buffer_write(file_resource);
            if (result.has_error()) {
                log_error("http_client_handler_file: write: %s", strerror(result.error().errcode));
            } else if (result.size() != bytes_readable) {
                log_error("http_client_handler_file: short_write");
            }
        }
        total_read += bytes_readable;
        buffer.reset();
    }

    // return bytes available or -1 if content length not present
    if (content_length >= 0) {
        return io_result(content_length - total_read);
    } else {
        return io_result(-1);
    }
}

bool http_client_handler_file::end_request()
{
    return true;
}
<|endoftext|>


<commit_before>#include "ofApp.h"
#include "ofxPS3EyeGrabber.h"

#define WIDTH 640
#define HEIGHT 480

//--------------------------------------------------------------
void ofApp::setup(){
    // Set the video grabber to the ofxPS3EyeGrabber.
    vidGrabber.setGrabber(std::make_shared<ofxPS3EyeGrabber>());
    vidGrabber.setup(WIDTH, HEIGHT);

    colorImg.allocate(WIDTH, HEIGHT);
    grayImage.allocate(WIDTH, HEIGHT);
    grayBg.allocate(WIDTH, HEIGHT);
    grayDiff.allocate(WIDTH, HEIGHT);

    bLearnBakground = true;
    threshold = 80;
}

//--------------------------------------------------------------
void ofApp::update(){
    vidGrabber.update();

    if(vidGrabber.isFrameNew())
    {
        colorImg.setFromPixels(vidGrabber.getPixels());
        grayImage = colorImg;
		if (bLearnBakground == true)
        {
            // the = sign copys the pixels from grayImage into grayBg (operator overloading)
			grayBg = grayImage;
			bLearnBakground = false;
		}

		// take the abs value of the difference between background and incoming and then threshold:
		grayDiff.absDiff(grayBg, grayImage);
		grayDiff.threshold(threshold);

		// find contours which are between the size of 20 pixels and 1/3 the w*h pixels.
		// also, find holes is set to true so we will get interior contours as well....
		//contourFinder.findContours(grayDiff, 20, (WIDTH*HEIGHT)/3, 10, true);	// find holes
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(0);
    ofSetColor(255);
    //vidGrabber.draw(0, 0);
    grayDiff.draw(0,0);
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

	switch (key){
		case ' ':
			bLearnBakground = true;
			break;
		case '+':
			threshold ++;
			if (threshold > 255) threshold = 255;
			break;
		case '-':
			threshold --;
			if (threshold < 0) threshold = 0;
			break;
	}
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<commit_msg>find and show contours<commit_after>#include "ofApp.h"
#include "ofxPS3EyeGrabber.h"

#define WIDTH 640
#define HEIGHT 480

//--------------------------------------------------------------
void ofApp::setup(){
    // Set the video grabber to the ofxPS3EyeGrabber.
    vidGrabber.setGrabber(std::make_shared<ofxPS3EyeGrabber>());
    vidGrabber.setup(WIDTH, HEIGHT);

    colorImg.allocate(WIDTH, HEIGHT);
    grayImage.allocate(WIDTH, HEIGHT);
    grayBg.allocate(WIDTH, HEIGHT);
    grayDiff.allocate(WIDTH, HEIGHT);

    bLearnBakground = true;
    threshold = 80;
}

//--------------------------------------------------------------
void ofApp::update(){
    vidGrabber.update();

    if(vidGrabber.isFrameNew())
    {
        colorImg.setFromPixels(vidGrabber.getPixels());
        grayImage = colorImg;
		if (bLearnBakground == true)
        {
            // the = sign copys the pixels from grayImage into grayBg (operator overloading)
			grayBg = grayImage;
			bLearnBakground = false;
		}

		// take the abs value of the difference between background and incoming and then threshold:
		grayDiff.absDiff(grayBg, grayImage);
		grayDiff.threshold(threshold);

		// find contours which are between the size of 20 pixels and 1/3 the w*h pixels.
		// also, find holes is set to true so we will get interior contours as well....
		contourFinder.findContours(grayDiff, 20, (WIDTH*HEIGHT)/3, 10, true);	// find holes
    }
}

//--------------------------------------------------------------
void ofApp::draw(){
    ofBackground(0);
    ofSetColor(255);
    //vidGrabber.draw(0, 0);
    colorImg.draw(0,0);
    //grayDiff.draw(0,0);

    for(int i = 0; i < contourFinder.nBlobs; i++)
    {
        contourFinder.blobs[i].draw(0,0);
    }
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){

	switch (key){
		case ' ':
			bLearnBakground = true;
			break;
		case '+':
			threshold ++;
			if (threshold > 255) threshold = 255;
			break;
		case '-':
			threshold --;
			if (threshold < 0) threshold = 0;
			break;
	}
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){

}
<|endoftext|>