Ejemplo n.º 1
0
void TiledBackingStore::invalidate(const IntRect& contentsDirtyRect)
{
    IntRect dirtyRect(mapFromContents(contentsDirtyRect));
    IntRect keepRectFitToTileSize = tileRectForCoordinate(tileCoordinateForPoint(m_keepRect.location()));
    keepRectFitToTileSize.unite(tileRectForCoordinate(tileCoordinateForPoint(innerBottomRight(m_keepRect))));

    // Only iterate on the part of the rect that we know we might have tiles.
    IntRect coveredDirtyRect = intersection(dirtyRect, keepRectFitToTileSize);
    Tile::Coordinate topLeft = tileCoordinateForPoint(coveredDirtyRect.location());
    Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(coveredDirtyRect));

    for (int yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
        for (int xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
            RefPtr<Tile> currentTile = tileAt(Tile::Coordinate(xCoordinate, yCoordinate));
            if (!currentTile)
                continue;
            // Pass the full rect to each tile as coveredDirtyRect might not
            // contain them completely and we don't want partial tile redraws.
#if PLATFORM(JS)
					fprintf(stderr, "WebKit: TiledBackingStore: invalidate: invalidating currentTile (x,y,w,h): %i %i %i %i\n",dirtyRect.x(),dirtyRect.y(),dirtyRect.width(),dirtyRect.height());
#endif
            currentTile->invalidate(dirtyRect);
        }
    }

    startTileBufferUpdateTimer();
}
Ejemplo n.º 2
0
void TiledDrawingAreaProxy::invalidate(const IntRect& contentsDirtyRect)
{
    IntRect dirtyRect(mapFromContents(contentsDirtyRect));

    TiledDrawingAreaTile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.topLeft());
    TiledDrawingAreaTile::Coordinate bottomRight = tileCoordinateForPoint(dirtyRect.bottomRight());

    IntRect coverRect = calculateCoverRect(m_previousVisibleRect);

    Vector<TiledDrawingAreaTile::Coordinate> tilesToRemove;

    for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
        for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
            RefPtr<TiledDrawingAreaTile> currentTile = tileAt(TiledDrawingAreaTile::Coordinate(xCoordinate, yCoordinate));
            if (!currentTile)
                continue;
            if (!currentTile->rect().intersects(dirtyRect))
                continue;
            // If a tile outside out current cover rect gets invalidated, just drop it instead of updating.
            if (!currentTile->rect().intersects(coverRect)) {
                tilesToRemove.append(currentTile->coordinate());
                continue;
            }
            currentTile->invalidate(dirtyRect);
        }
    }

    unsigned removeCount = tilesToRemove.size();
    for (unsigned n = 0; n < removeCount; ++n)
        removeTile(tilesToRemove[n]);

    startTileBufferUpdateTimer();
}
	//---------------------------------------------------------------------
	void TerrainLayerBlendMap::blit(const PixelBox &src, const Box &dstBox)
	{
		const PixelBox* srcBox = &src;

		if (srcBox->getWidth() != dstBox.getWidth() || srcBox->getHeight() != dstBox.getHeight())
		{
			// we need to rescale src to dst size first (also confvert format)
			void* tmpData = OGRE_MALLOC(dstBox.getWidth() * dstBox.getHeight(), MEMCATEGORY_GENERAL);
			srcBox = OGRE_NEW PixelBox(dstBox.getWidth(), dstBox.getHeight(), 1, PF_L8, tmpData);

			Image::scale(src, *srcBox);
		}

		// pixel conversion
		PixelBox dstMemBox(dstBox, PF_L8, mData);
		PixelUtil::bulkPixelConversion(*srcBox, dstMemBox);

		if (srcBox != &src)
		{
			// free temp
			OGRE_FREE(srcBox->data, MEMCATEGORY_GENERAL);
			OGRE_DELETE srcBox;
			srcBox = 0;
		}

		Rect dRect(dstBox.left, dstBox.top, dstBox.right, dstBox.bottom);
		dirtyRect(dRect);

	}
Ejemplo n.º 4
0
void BrushToolEdit::drawColor(const QPoint &pt, Map &&map)
{
    Terrain *tip = tool->tip(pt).data();

    // compute affected rectangle
    QRect dirtyRect(pt, tip->size());
    dirtyRect = dirtyRect.intersected(QRect(QPoint(0, 0), terrain->size()));

    if (!dirtyRect.isValid()) {
        return;
    }

    // get "before" terrain
    if (tool->before_ == nullptr || tool->before_->size() != tip->size()) {
        tool->before_ = QSharedPointer<Terrain>::create(tip->size());
    }
    Terrain *before = tool->before_.data();
    edit->copyBeforeTo(dirtyRect, terrain, before);

    edit->beginEdit(dirtyRect, terrain);
    for (int y = 0; y < dirtyRect.height(); ++y) {
        for (int x = 0; x < dirtyRect.width(); ++x) {
            int cx = x + dirtyRect.left();
            int cy = y + dirtyRect.top();
            int tx = cx - pt.x();
            int ty = cy - pt.y();
            map(terrain->color(cx, cy), before->color(x, y), tip->landform(tx, ty));
        }
    }
    edit->endEdit(terrain);
}
	//---------------------------------------------------------------------
	void TerrainLayerBlendMap::dirty()
	{
		Rect rect;
		rect.top = 0; rect.bottom = mBuffer->getHeight();
		rect.left = 0; rect.right = mBuffer->getWidth();
		dirtyRect(rect);

	}
void KisSimpleUpdateQueueTest::testChecksum()
{
    QRect imageRect(0,0,512,512);
    QRect dirtyRect(100,100,100,100);

    const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8();
    KisImageSP image = new KisImage(0, imageRect.width(), imageRect.height(), colorSpace, "test");

    KisLayerSP paintLayer1 = new KisPaintLayer(image, "paint1", OPACITY_OPAQUE_U8);
    KisAdjustmentLayerSP adjustmentLayer = new KisAdjustmentLayer(image, "adj", 0, 0);

    image->lock();
    image->addNode(paintLayer1, image->rootLayer());
    image->addNode(adjustmentLayer, image->rootLayer());
    image->unlock();

    KisFilterSP filter = KisFilterRegistry::instance()->value("blur");
    Q_ASSERT(filter);
    KisFilterConfiguration *configuration = filter->defaultConfiguration(0);


    KisTestableSimpleUpdateQueue queue;
    KisWalkersList& walkersList = queue.getWalkersList();

    {
        TestUtil::LodOverride l(1, image);
        queue.addUpdateJob(adjustmentLayer, dirtyRect, imageRect, 1);
        QCOMPARE(walkersList[0]->checksumValid(), true);
        QCOMPARE(walkersList[0]->levelOfDetail(), 1);
    }

    adjustmentLayer->setFilter(configuration);

    {
        TestUtil::LodOverride l(1, image);
        QCOMPARE(walkersList[0]->checksumValid(), false);
    }


    QVector<KisUpdateJobItem*> jobs;
    KisTestableUpdaterContext context(2);

    {
        TestUtil::LodOverride l(1, image);
        queue.processQueue(context);
    }

    jobs = context.getJobs();

    {
        TestUtil::LodOverride l(1, image);
        QCOMPARE(jobs[0]->walker()->checksumValid(), true);
    }
}
void KisPrescaledProjectionTest::benchmarkUpdate()
{
    QImage referenceImage(QString(FILES_DATA_DIR) + QDir::separator() + "lena.png");
    QRect imageRect = QRect(QPoint(0,0), referenceImage.size());

    const KoColorSpace * cs = KoColorSpaceRegistry::instance()->rgb8();
    KisImageSP image = new KisImage(0, imageRect.width(), imageRect.height(), cs, "projection test");

    // set up 300dpi
    image->setResolution(300 / 72 , 300 / 72);

    KisPaintLayerSP layer = new KisPaintLayer(image, "paint1", OPACITY_OPAQUE_U8, cs);
    layer->paintDevice()->convertFromQImage(referenceImage, 0);

    image->addNode(layer, image->rootLayer(), 0);

    KisPrescaledProjection projection;

    KisCoordinatesConverter converter;
    converter.setImage(image);
    projection.setCoordinatesConverter(&converter);
    projection.setMonitorProfile(0,
                                 KoColorConversionTransformation::internalRenderingIntent(),
                                 KoColorConversionTransformation::internalConversionFlags());
    projection.setImage(image);

    // Emulate "Use same aspect as pixels"
    converter.setResolution(image->xRes(), image->yRes());

    converter.setZoom(1.0);

    KisUpdateInfoSP info = projection.updateCache(image->bounds());
    projection.recalculateCache(info);

    QCOMPARE(imageRect, QRect(0,0,512,512));

    QRect dirtyRect(0,0,20,20);
    const qint32 numShifts = 25;
    const QPoint offset(dirtyRect.width(),dirtyRect.height());

    //CALLGRIND_START_INSTRUMENTATION;

    QBENCHMARK {
        for(qint32 i = 0; i < numShifts; i++) {
            KisUpdateInfoSP tempInfo = projection.updateCache(dirtyRect);
            projection.recalculateCache(tempInfo);

            dirtyRect.translate(offset);
        }
    }

    //CALLGRIND_STOP_INSTRUMENTATION;

}
Ejemplo n.º 8
0
void Caret::render( GfxDevice * pDevice, Rect cell, const Rect& clip )
{
    if( m_ticks < m_cycleLength / 2 )
    {
        Rect r = dirtyRect(cell);
        BlendMode oldMode = pDevice->blendMode();
        pDevice->setBlendMode(BlendMode::Invert);
        pDevice->fill( Rect(r,clip), Color::White );
        pDevice->setBlendMode(oldMode);
    }

    m_bNeedToRender = false;
}
Ejemplo n.º 9
0
void TiledBackingStore::invalidate(const IntRect& contentsDirtyRect)
{
    IntRect dirtyRect(mapFromContents(contentsDirtyRect));
    
    Tile::Coordinate topLeft = tileCoordinateForPoint(dirtyRect.location());
    Tile::Coordinate bottomRight = tileCoordinateForPoint(innerBottomRight(dirtyRect));
    
    for (unsigned yCoordinate = topLeft.y(); yCoordinate <= bottomRight.y(); ++yCoordinate) {
        for (unsigned xCoordinate = topLeft.x(); xCoordinate <= bottomRight.x(); ++xCoordinate) {
            RefPtr<Tile> currentTile = tileAt(Tile::Coordinate(xCoordinate, yCoordinate));
            if (!currentTile)
                continue;
            currentTile->invalidate(dirtyRect);
        }
    }

    startTileBufferUpdateTimer();
}
Ejemplo n.º 10
0
void PageWidgetDelegate::paint(Page* page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background)
{
    if (rect.isEmpty())
        return;
    GraphicsContextBuilder builder(canvas);
    GraphicsContext& gc = builder.context();
    gc.platformContext()->setDrawingToImageBuffer(background == Opaque ? false : true);
    gc.applyDeviceScaleFactor(page->deviceScaleFactor());
    IntRect dirtyRect(rect);
    gc.save();
    FrameView* view = mainFrameView(page);
    // FIXME: Can we remove the mainFrame()->document() check?
    if (view && page->mainFrame()->document()) {
        gc.clip(dirtyRect);
        view->paint(&gc, dirtyRect);
        if (overlays)
            overlays->paintWebFrame(gc);
    } else
        gc.fillRect(dirtyRect, Color::white, ColorSpaceDeviceRGB);
    gc.restore();
}
Ejemplo n.º 11
0
void Brush::applyLayerBrush(long int x, long int y, const Ogre::Vector3& position)
{
    auto ter = m_group->getTerrain(x, y);
    if(!ter)
        return;
    auto indices = (position - ter->getPosition())/ter->getWorldSize();
    indices += 0.5;
    auto cmd = dynamic_cast<undo::BlendmapEdit*>(m_currentCommand);
    assert(cmd != nullptr);
    cmd->monitorTerrain(x, y);
    size_t size = ter->getLayerBlendMapSize();
    indices *= size;
    float brushSize = m_settings[m_mode].size/ter->getWorldSize() * size;
    float strength = m_settings[m_mode].strength * ((QApplication::queryKeyboardModifiers() & Qt::ShiftModifier)? -0.01f : 0.01f);
    auto layer = ter->getLayerBlendMap(cmd->getLayerIndex());
    auto data = layer->getBlendPointer();
    Ogre::Rect rect(Ogre::Math::Clamp<int>(indices.x-brushSize/2, 0, size),
                    Ogre::Math::Clamp<int>(indices.z-brushSize/2, 0, size),
                    Ogre::Math::Clamp<int>(indices.x+brushSize/2, 0, size),
                    Ogre::Math::Clamp<int>(indices.z+brushSize/2, 0, size));
    if(rect.bottom == rect.top || rect.left == rect.right)
        // brush does not reach this terrain
        return;
    for(int ix=rect.left; ix<rect.right; ix++) {
        for(int iy=rect.top; iy<rect.bottom; iy++) {
            float dist = std::sqrt(std::pow(ix-indices.x, 2) + std::pow(iy-indices.z, 2));
            float distWeight = brushFunction(dist/brushSize*2, m_settings[m_mode].hardness);
//                             std::cout << dist << " " << brushSize/2 << " " << distWeight << std::endl;
            data[iy*size+ix] += distWeight*strength;
//                             data[iy*size+ix] -= 0.1;
            if(data[iy*size+ix] > 1.0)
                data[iy*size+ix] = 1.0;
            if(data[iy*size+ix] < 0.0)
                data[iy*size+ix] = 0.0;
//                             std::cout << data[iy*size+ix] << " ";
        }
    }
    layer->dirtyRect(rect);
    layer->update();
}
Ejemplo n.º 12
0
void PageWidgetDelegate::paint(Page* page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background)
{
    if (rect.isEmpty())
        return;
    GraphicsContext gc(canvas);
    gc.setCertainlyOpaque(background == Opaque);
    gc.applyDeviceScaleFactor(page->deviceScaleFactor());
    gc.setUseHighResMarkers(page->deviceScaleFactor() > 1.5f);
    IntRect dirtyRect(rect);
    gc.save(); // Needed to save the canvas, not the GraphicsContext.
    FrameView* view = mainFrameView(page);
    // FIXME: Can we remove the mainFrame()->document() check?
    if (view && page->mainFrame()->document()) {
        gc.clip(dirtyRect);
        view->paint(&gc, dirtyRect);
        if (overlays)
            overlays->paintWebFrame(gc);
    } else {
        gc.fillRect(dirtyRect, Color::white);
    }
    gc.restore();
}
Ejemplo n.º 13
0
void PageWidgetDelegate::paint(Page& page, PageOverlayList* overlays, WebCanvas* canvas, const WebRect& rect, CanvasBackground background, LocalFrame& root)
{
    if (rect.isEmpty())
        return;
    GraphicsContext gc(canvas, nullptr);
    gc.setCertainlyOpaque(background == Opaque);
    float scaleFactor = page.deviceScaleFactor();
    gc.scale(scaleFactor, scaleFactor);
    gc.setDeviceScaleFactor(scaleFactor);
    IntRect dirtyRect(rect);
    gc.save(); // Needed to save the canvas, not the GraphicsContext.
    FrameView* view = root.view();
    if (view) {
        gc.clip(dirtyRect);
        view->paint(&gc, dirtyRect);
        if (overlays)
            overlays->paintWebFrame(gc);
    } else {
        gc.fillRect(dirtyRect, Color::white);
    }
    gc.restore();
}
Ejemplo n.º 14
0
void Brush::applyHeightBrush(long int x, long int y, const Ogre::Vector3& position, float average)
{
    auto ter = m_group->getTerrain(x, y);
    if(!ter)
        return;
    auto indices = (position - ter->getPosition())/ter->getWorldSize();
    indices += 0.5;
    auto cmd = dynamic_cast<undo::HeightmapEdit*>(m_currentCommand);
    assert(cmd != nullptr);
    indices.z = 1.0f - indices.z;
    indices *= ter->getSize();
    float* heightdata = ter->getHeightData();
    float brushSize = m_settings[m_mode].size/ter->getWorldSize() * ter->getSize();
    size_t terSize = ter->getSize();
    // LEFT  TOP  RIGHT  BOTTOM
    Ogre::Rect rect(Ogre::Math::Clamp<int>(indices.x-brushSize/2, 0, terSize),  // left
                    Ogre::Math::Clamp<int>(indices.z-brushSize/2, 0, terSize),  // top
                    Ogre::Math::Clamp<int>(indices.x+brushSize/2, 0, terSize),  // right
                    Ogre::Math::Clamp<int>(indices.z+brushSize/2, 0, terSize)); // bottom
    std::cout << rect << std::endl;
    if(rect.bottom == rect.top || rect.left == rect.right)
        // brush does not reach this terrain
        return;
    cmd->monitorTerrain(x, y, rect);
    if(m_mode == M_HEIGHT_RAISE) {
        float strength = m_settings[m_mode].strength *
                        ((QApplication::queryKeyboardModifiers()
                        & Qt::ShiftModifier)? -0.1f : 0.1f);
        for(int ix=rect.left; ix<rect.right; ix++) {
            for(int iy=rect.top; iy<rect.bottom; iy++) {
                float dist = std::sqrt(std::pow(ix-indices.x, 2) + std::pow(iy-indices.z, 2));
                heightdata[iy*terSize+ix] += brushFunction(dist/brushSize*2,
                                                                m_settings[m_mode].hardness) * strength;
            }
        }
    } else if(m_mode == M_HEIGHT_SMOOTH) {
        for(int ix=rect.left; ix<rect.right; ix++) {
            for(int iy=rect.top; iy<rect.bottom; iy++) {
                float dist = std::sqrt(std::pow(ix-indices.x, 2) + std::pow(iy-indices.z, 2));
                float weight = brushFunction(dist/brushSize*2, m_settings[m_mode].hardness);
                float difference = average - heightdata[iy*terSize+ix];
                difference *= m_settings[m_mode].strength/10.0f;
                heightdata[iy*terSize+ix] += weight*difference;
            }
        }
    } else if(m_mode == M_HEIGHT_FLATTEN) {
        if(QApplication::queryKeyboardModifiers() & Qt::ShiftModifier) {
            m_height = position.y;
            m_drawer->setBrushOptions(m_settings[m_mode].size,
                                        m_settings[m_mode].hardness,
                                        m_height);
        } else {
            for(int ix=rect.left; ix<rect.right; ix++) {
                for(int iy=rect.top; iy<rect.bottom; iy++) {
                    float dist = std::sqrt(std::pow(ix-indices.x, 2) + std::pow(iy-indices.z, 2));
                    float weight = brushFunction(dist/brushSize*2, m_settings[m_mode].hardness);
                    float difference = m_height - heightdata[iy*terSize+ix];
                    difference *= m_settings[m_mode].strength/10.0f;
                    heightdata[iy*terSize+ix] += weight*difference;
                }
            }
        }
    }
    ter->dirtyRect(rect);
    ter->updateGeometryWithoutNotifyNeighbours();
    ter->update();
}
 void didProcessTask() override {
   ASSERT_TRUE(m_isDirty);
   FloatRect dirtyRect(0, 0, 1, 1);
   m_imageBuffer->finalizeFrame(dirtyRect);
   ASSERT_FALSE(m_isDirty);
 }
	//---------------------------------------------------------------------
	void TerrainLayerBlendMap::setBlendValue(size_t x, size_t y, float val)
	{
		*(mData + y * mBuffer->getWidth() + x) = val;
		dirtyRect(Rect(x, y, x+1, y+1));

	}
Ejemplo n.º 17
0
void BrushToolEdit::drawBlur(const QPoint &pt, float amount)
{
    Terrain *tip = tool->tip(pt).data();

    // compute affected rectangle
    QRect dirtyRect(pt, tip->size());
    dirtyRect = dirtyRect.intersected(QRect(QPoint(0, 0), terrain->size()));

    if (!dirtyRect.isValid()) {
        return;
    }

    edit->beginEdit(dirtyRect, terrain);

    QSize tSize = terrain->size();
    QSize tipSize = tip->size();
    QSize blurBufferSize(dirtyRect.width() + 6, dirtyRect.height() + 6);
    TemporaryBuffer<__m128> blurBuffer1(blurBufferSize.width() * blurBufferSize.height(), 16);
    TemporaryBuffer<__m128> blurBuffer2(blurBufferSize.width() * blurBufferSize.height(), 16);
    TemporaryBuffer<float> tipBuffer(blurBufferSize.width() * blurBufferSize.height(), 4);

    for (int y = 0; y < blurBufferSize.height(); ++y) {
        int cy = y + dirtyRect.top() - 3;
        cy = std::max(std::min(cy, tSize.height() - 1), 0);
        for (int x = 0; x < blurBufferSize.width(); ++x) {
            int cx = x + dirtyRect.left() - 3;
            cx = std::max(std::min(cx, tSize.width() - 1), 0);

            quint32 color = terrain->color(cx, cy);
            auto colorMM = _mm_setr_epi32(color, 0, 0, 0);
            colorMM = _mm_unpacklo_epi8(colorMM, _mm_setzero_si128());
            colorMM = _mm_unpacklo_epi16(colorMM, _mm_setzero_si128());
            auto colorF = _mm_cvtepi32_ps(colorMM);
            _mm_store_ps(reinterpret_cast<float *>(blurBuffer1 + x + y * blurBufferSize.width()), colorF);
        }
    }
    for (int y = 0; y < blurBufferSize.height(); ++y) {
        int cy = y + dirtyRect.top() - 3;
        int ty = cy - pt.y();
        if (ty >= 0 && ty < tipSize.height()) {
            for (int x = 0; x < blurBufferSize.width(); ++x) {
                int cx = x + dirtyRect.left() - 3;
                int tx = cx - pt.x();
                tipBuffer[x + y * blurBufferSize.width()] =
                        tx >= 0 && tx < tipSize.width() ?
                            tip->landform(tx, ty) * amount :
                            0.f;
            }
        } else {
            std::fill(&tipBuffer[y * blurBufferSize.width()],
                    &tipBuffer[(y + 1) * blurBufferSize.width()], 0.f);
        }
    }

    // apply horizontal blur
    for (int y = 0; y < blurBufferSize.height(); ++y) {
        __m128 *inBuf = blurBuffer1 + y * blurBufferSize.width();
        __m128 *outBuf = blurBuffer2 + y * blurBufferSize.width();
        float *varBuf = tipBuffer + y * blurBufferSize.width();
        for (int x = 3; x < blurBufferSize.width() - 3; ++x) {
            float variance = varBuf[x];
            __m128 kernel = globalGaussianKernelTable.fetch(variance);

            // sample input
            __m128 p1 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x));
            p1 = _mm_add_ps(p1, p1);
            __m128 p2 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x + 1));
            p2 = _mm_add_ps(p2, _mm_load_ps(reinterpret_cast<float *>(inBuf + x - 1)));
            __m128 p3 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x + 2));
            p3 = _mm_add_ps(p3, _mm_load_ps(reinterpret_cast<float *>(inBuf + x - 2)));
            __m128 p4 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x + 3));
            p4 = _mm_add_ps(p4, _mm_load_ps(reinterpret_cast<float *>(inBuf + x - 3)));

            // apply kernel
            p1 = _mm_mul_ps(p1, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(0, 0, 0, 0)));
            p2 = _mm_mul_ps(p2, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(1, 1, 1, 1)));
            p3 = _mm_mul_ps(p3, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(2, 2, 2, 2)));
            p4 = _mm_mul_ps(p4, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(3, 3, 3, 3)));

            p1 = _mm_add_ps(p1, p2);
            p3 = _mm_add_ps(p3, p4);
            auto p = _mm_add_ps(p1, p3);

            // store
            _mm_store_ps(reinterpret_cast<float *>(outBuf + x), p);
        }
    }

    // apply vertical blur
    for (int y = 3; y < blurBufferSize.height() - 3; ++y) {
        __m128 *inBuf = blurBuffer2 + y * blurBufferSize.width();
        __m128 *outBuf = blurBuffer1 + y * blurBufferSize.width();
        float *varBuf = tipBuffer + y * blurBufferSize.width();
        for (int x = 3; x < blurBufferSize.width() - 3; x += 1) {
            // fetch kernel
            __m128 kernel = globalGaussianKernelTable.fetch(varBuf[x]);

            // load input
            __m128 p1 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x));
            p1 = _mm_add_ps(p1, p1);
            __m128 p2 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x - blurBufferSize.width()));
            p2 = _mm_add_ps(p2, _mm_load_ps(reinterpret_cast<float *>(inBuf + x + blurBufferSize.width())));
            __m128 p3 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x - blurBufferSize.width() * 2));
            p3 = _mm_add_ps(p3, _mm_load_ps(reinterpret_cast<float *>(inBuf + x + blurBufferSize.width() * 2)));
            __m128 p4 = _mm_load_ps(reinterpret_cast<float *>(inBuf + x - blurBufferSize.width() * 3));
            p4 = _mm_add_ps(p4, _mm_load_ps(reinterpret_cast<float *>(inBuf + x + blurBufferSize.width() * 3)));

            // apply kernel
            p1 = _mm_mul_ps(p1, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(0, 0, 0, 0)));
            p2 = _mm_mul_ps(p2, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(1, 1, 1, 1)));
            p3 = _mm_mul_ps(p3, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(2, 2, 2, 2)));
            p4 = _mm_mul_ps(p4, _mm_shuffle_ps(kernel, kernel, _MM_SHUFFLE(3, 3, 3, 3)));
            p1 = _mm_add_ps(p1, p2);
            p3 = _mm_add_ps(p3, p4);
            auto p = _mm_add_ps(p1, p3);

            // store
            _mm_store_ps(reinterpret_cast<float *>(outBuf + x), p);
        }
    }

    for (int y = 0; y < dirtyRect.height(); ++y) {
        __m128 *inBuf = blurBuffer1 + (y + 3) * blurBufferSize.width() + 3;
        for (int x = 0; x < dirtyRect.width(); ++x) {
            int cx = x + dirtyRect.left();
            int cy = y + dirtyRect.top();
            auto colorF = _mm_load_ps(reinterpret_cast<float *>(inBuf + x));
            colorF = _mm_add_ps(colorF, _mm_set1_ps(0.5f));
            colorF = _mm_add_ps(colorF, globalDitherSampler.getM128());
            auto colorMM = _mm_cvttps_epi32(colorF);
            colorMM = _mm_packs_epi32(colorMM, colorMM);
            colorMM = _mm_packus_epi16(colorMM, colorMM);
            _mm_store_ss(reinterpret_cast<float*>(&terrain->color(cx, cy)), _mm_castsi128_ps(colorMM));
        }
    }
    edit->endEdit(terrain);
}
Ejemplo n.º 18
0
void BrushToolEdit::drawSmoothen(const QPoint &pt, float amount)
{
    Terrain *tip = tool->tip(pt).data();

    // compute affected rectangle
    QRect dirtyRect(pt, tip->size());
    dirtyRect = dirtyRect.intersected(QRect(QPoint(0, 0), terrain->size()));

    if (!dirtyRect.isValid()) {
        return;
    }

    edit->beginEdit(dirtyRect, terrain);

    QSize tSize = terrain->size();
    QSize tipSize = tip->size();
    QSize blurBufferSize(dirtyRect.width() + 6, dirtyRect.height() + 6);
    TemporaryBuffer<float> blurBuffer1(blurBufferSize.width() * blurBufferSize.height(), 4);
    TemporaryBuffer<float> blurBuffer2(blurBufferSize.width() * blurBufferSize.height(), 4);
    TemporaryBuffer<float> tipBuffer(blurBufferSize.width() * blurBufferSize.height(), 4);

    for (int y = 0; y < blurBufferSize.height(); ++y) {
        int cy = y + dirtyRect.top() - 3;
        cy = std::max(std::min(cy, tSize.height() - 1), 0);
        for (int x = 0; x < blurBufferSize.width(); ++x) {
            int cx = x + dirtyRect.left() - 3;
            cx = std::max(std::min(cx, tSize.width() - 1), 0);
            blurBuffer1[x + y * blurBufferSize.width()] =
                    terrain->landform(cx, cy);
        }
    }
    for (int y = 0; y < blurBufferSize.height(); ++y) {
        int cy = y + dirtyRect.top() - 3;
        int ty = cy - pt.y();
        if (ty >= 0 && ty < tipSize.height()) {
            for (int x = 0; x < blurBufferSize.width(); ++x) {
                int cx = x + dirtyRect.left() - 3;
                int tx = cx - pt.x();
                tipBuffer[x + y * blurBufferSize.width()] =
                        tx >= 0 && tx < tipSize.width() ?
                            tip->landform(tx, ty) * amount :
                            0.f;
            }
        } else {
            std::fill(&tipBuffer[y * blurBufferSize.width()],
                    &tipBuffer[(y + 1) * blurBufferSize.width()], 0.f);
        }
    }

    // apply horizontal blur
    for (int y = 0; y < blurBufferSize.height(); ++y) {
        float *inBuf = blurBuffer1 + y * blurBufferSize.width();
        float *outBuf = blurBuffer2 + y * blurBufferSize.width();
        float *varBuf = tipBuffer + y * blurBufferSize.width();
        for (int x = 3; x < blurBufferSize.width() - 3; ++x) {
            float variance = varBuf[x];
            __m128 kernel = globalGaussianKernelTable.fetch(variance);

            // sample input
            __m128 p1 = _mm_loadu_ps(inBuf + x - 3);
            __m128 p2 = _mm_loadu_ps(inBuf + x);
            p1 = _mm_shuffle_ps(p1, p1, _MM_SHUFFLE(0, 1, 2, 3));
            auto p = _mm_add_ps(p1, p2);

            // apply kernel
            p = _mm_mul_ps(p, kernel);
            p = _mm_hadd_ps(p, p);
            p = _mm_hadd_ps(p, p);

            // write
            _mm_store_ss(outBuf + x, p);
        }
    }

    // apply vertical blur
    for (int y = 3; y < blurBufferSize.height() - 3; ++y) {
        float *inBuf = blurBuffer2 + y * blurBufferSize.width();
        float *outBuf = blurBuffer1 + y * blurBufferSize.width();
        float *varBuf = tipBuffer + y * blurBufferSize.width();
        for (int x = 0; x < blurBufferSize.width() - 3; x += 4) {
            // fetch kernel
            __m128 kernel1 = globalGaussianKernelTable.fetch(varBuf[x]);
            __m128 kernel2 = globalGaussianKernelTable.fetch(varBuf[x + 1]);
            __m128 kernel3 = globalGaussianKernelTable.fetch(varBuf[x + 2]);
            __m128 kernel4 = globalGaussianKernelTable.fetch(varBuf[x + 3]);
            _MM_TRANSPOSE4_PS(kernel1, kernel2, kernel3, kernel4);

            // load input
            __m128 p1 = _mm_loadu_ps(inBuf + x);
            p1 = _mm_add_ps(p1, p1);
            __m128 p2 = _mm_loadu_ps(inBuf + x - blurBufferSize.width());
            p2 = _mm_add_ps(p2, _mm_loadu_ps(inBuf + x + blurBufferSize.width()));
            __m128 p3 = _mm_loadu_ps(inBuf + x - blurBufferSize.width() * 2);
            p3 = _mm_add_ps(p3, _mm_loadu_ps(inBuf + x + blurBufferSize.width() * 2));
            __m128 p4 = _mm_loadu_ps(inBuf + x - blurBufferSize.width() * 3);
            p4 = _mm_add_ps(p4, _mm_loadu_ps(inBuf + x + blurBufferSize.width() * 3));

            // apply kernel
            p1 = _mm_mul_ps(p1, kernel1);
            p2 = _mm_mul_ps(p2, kernel2);
            p3 = _mm_mul_ps(p3, kernel3);
            p4 = _mm_mul_ps(p4, kernel4);
            p1 = _mm_add_ps(p1, p2);
            p3 = _mm_add_ps(p3, p4);
            auto p = _mm_add_ps(p1, p3);

            // store
            _mm_storeu_ps(outBuf + x, p);
        }
    }

    for (int y = 0; y < dirtyRect.height(); ++y) {
        float *inBuf = blurBuffer1 + (y + 3) * blurBufferSize.width() + 3;
        for (int x = 0; x < dirtyRect.width(); ++x) {
            int cx = x + dirtyRect.left();
            int cy = y + dirtyRect.top();
            terrain->landform(cx, cy) = inBuf[x];
        }
    }
    edit->endEdit(terrain);
}
Ejemplo n.º 19
0
void ContentLayerChromium::updateContents()
{
    RenderLayerBacking* backing = static_cast<RenderLayerBacking*>(m_owner->client());
    if (!backing || backing->paintingGoesToWindow())
        return;

    ASSERT(drawsContent());

    ASSERT(layerRenderer());

    // FIXME: Remove this test when tiled layers are implemented.
    m_skipsDraw = false;
    if (!layerRenderer()->checkTextureSize(m_bounds)) {
        m_skipsDraw = true;
        return;
    }

    void* pixels = 0;
    IntRect dirtyRect(m_dirtyRect);
    IntSize requiredTextureSize;
    IntSize bitmapSize;

    requiredTextureSize = m_bounds;
    IntRect boundsRect(IntPoint(0, 0), m_bounds);

    // If the texture needs to be reallocated then we must redraw the entire
    // contents of the layer.
    if (requiredTextureSize != m_allocatedTextureSize)
        dirtyRect = boundsRect;
    else {
        // Clip the dirtyRect to the size of the layer to avoid drawing outside
        // the bounds of the backing texture.
        dirtyRect.intersect(boundsRect);
    }

#if PLATFORM(SKIA)
    const SkBitmap* skiaBitmap = 0;
    OwnPtr<skia::PlatformCanvas> canvas;
    OwnPtr<PlatformContextSkia> skiaContext;
    OwnPtr<GraphicsContext> graphicsContext;

    canvas.set(new skia::PlatformCanvas(dirtyRect.width(), dirtyRect.height(), false));
    skiaContext.set(new PlatformContextSkia(canvas.get()));

    // This is needed to get text to show up correctly.
    // FIXME: Does this take us down a very slow text rendering path?
    skiaContext->setDrawingToImageBuffer(true);

    graphicsContext.set(new GraphicsContext(reinterpret_cast<PlatformGraphicsContext*>(skiaContext.get())));

    // Bring the canvas into the coordinate system of the paint rect.
    canvas->translate(static_cast<SkScalar>(-dirtyRect.x()), static_cast<SkScalar>(-dirtyRect.y()));

    m_owner->paintGraphicsLayerContents(*graphicsContext, dirtyRect);
    const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
    skiaBitmap = &bitmap;
    ASSERT(skiaBitmap);

    SkAutoLockPixels lock(*skiaBitmap);
    SkBitmap::Config skiaConfig = skiaBitmap->config();
    // FIXME: do we need to support more image configurations?
    if (skiaConfig == SkBitmap::kARGB_8888_Config) {
        pixels = skiaBitmap->getPixels();
        bitmapSize = IntSize(skiaBitmap->width(), skiaBitmap->height());
    }
#elif PLATFORM(CG)
    Vector<uint8_t> tempVector;
    int rowBytes = 4 * dirtyRect.width();
    tempVector.resize(rowBytes * dirtyRect.height());
    memset(tempVector.data(), 0, tempVector.size());
    RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB());
    RetainPtr<CGContextRef> contextCG(AdoptCF, CGBitmapContextCreate(tempVector.data(),
                                                                     dirtyRect.width(), dirtyRect.height(), 8, rowBytes,
                                                                     colorSpace.get(),
                                                                     kCGImageAlphaPremultipliedLast));
    CGContextTranslateCTM(contextCG.get(), 0, dirtyRect.height());
    CGContextScaleCTM(contextCG.get(), 1, -1);

    GraphicsContext graphicsContext(contextCG.get());

    // Translate the graphics context into the coordinate system of the dirty rect.
    graphicsContext.translate(-dirtyRect.x(), -dirtyRect.y());

    m_owner->paintGraphicsLayerContents(graphicsContext, dirtyRect);

    pixels = tempVector.data();
    bitmapSize = dirtyRect.size();
#else
#error "Need to implement for your platform."
#endif

    unsigned textureId = m_contentsTexture;
    if (!textureId)
        textureId = layerRenderer()->createLayerTexture();

    if (pixels)
        updateTextureRect(pixels, bitmapSize, requiredTextureSize,  dirtyRect, textureId);
}