/*
 * Copyright 2007 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkPicture.h"

#include "SkImageGenerator.h"
#include "SkMathPriv.h"
#include "SkPictureCommon.h"
#include "SkPictureData.h"
#include "SkPicturePlayback.h"
#include "SkPicturePriv.h"
#include "SkPictureRecord.h"
#include "SkPictureRecorder.h"
#include "SkSerialProcs.h"
#include "SkTo.h"
#include <atomic>

// When we read/write the SkPictInfo via a stream, we have a sentinel byte right after the info.
// Note: in the read/write buffer versions, we have a slightly different convention:
//      We have a sentinel int32_t:
//          0 : failure
//          1 : PictureData
//         <0 : -size of the custom data
enum {
    kFailure_TrailingStreamByteAfterPictInfo     = 0,   // nothing follows
    kPictureData_TrailingStreamByteAfterPictInfo = 1,   // SkPictureData follows
    kCustom_TrailingStreamByteAfterPictInfo      = 2,   // -size32 follows
};

/* SkPicture impl.  This handles generic responsibilities like unique IDs and serialization. */

SkPicture::SkPicture() {
    static std::atomic<uint32_t> nextID{1};
    do {
        fUniqueID = nextID.fetch_add(+1, std::memory_order_relaxed);
    } while (fUniqueID == 0);
}

static const char kMagic[] = { 's', 'k', 'i', 'a', 'p', 'i', 'c', 't' };

SkPictInfo SkPicture::createHeader() const {
    SkPictInfo info;
    // Copy magic bytes at the beginning of the header
    static_assert(sizeof(kMagic) == 8, "");
    static_assert(sizeof(kMagic) == sizeof(info.fMagic), "");
    memcpy(info.fMagic, kMagic, sizeof(kMagic));

    // Set picture info after magic bytes in the header
    info.setVersion(CURRENT_PICTURE_VERSION);
    info.fCullRect = this->cullRect();
    return info;
}

bool SkPicture::IsValidPictInfo(const SkPictInfo& info) {
    if (0 != memcmp(info.fMagic, kMagic, sizeof(kMagic))) {
        return false;
    }
    if (info.getVersion() < MIN_PICTURE_VERSION || info.getVersion() > CURRENT_PICTURE_VERSION) {
        return false;
    }
    return true;
}

bool SkPicture::StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
    if (!stream) {
        return false;
    }

    SkPictInfo info;
    SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
    if (stream->read(&info.fMagic, sizeof(kMagic)) != sizeof(kMagic)) {
        return false;
    }

    uint32_t version;
    if (!stream->readU32(&version)) { return false; }
    info.setVersion(version);
    if (!stream->readScalar(&info.fCullRect.fLeft  )) { return false; }
    if (!stream->readScalar(&info.fCullRect.fTop   )) { return false; }
    if (!stream->readScalar(&info.fCullRect.fRight )) { return false; }
    if (!stream->readScalar(&info.fCullRect.fBottom)) { return false; }
    if (info.getVersion() < SkReadBuffer::kRemoveHeaderFlags_Version) {
        if (!stream->readU32(nullptr)) { return false; }
    }

    if (!IsValidPictInfo(info)) { return false; }

    if (pInfo) { *pInfo = info; }
    return true;
}
bool SkPicture_StreamIsSKP(SkStream* stream, SkPictInfo* pInfo) {
    return SkPicture::StreamIsSKP(stream, pInfo);
}

bool SkPicture::BufferIsSKP(SkReadBuffer* buffer, SkPictInfo* pInfo) {
    SkPictInfo info;
    SkASSERT(sizeof(kMagic) == sizeof(info.fMagic));
    if (!buffer->readByteArray(&info.fMagic, sizeof(kMagic))) {
        return false;
    }

    info.setVersion(buffer->readUInt());
    buffer->readRect(&info.fCullRect);
    if (info.getVersion() < SkReadBuffer::kRemoveHeaderFlags_Version) {
        (void)buffer->readUInt();   // used to be flags
    }

    if (IsValidPictInfo(info)) {
        if (pInfo) { *pInfo = info; }
        return true;
    }
    return false;
}

sk_sp<SkPicture> SkPicture::Forwardport(const SkPictInfo& info,
                                        const SkPictureData* data,
                                        SkReadBuffer* buffer) {
    if (!data) {
        return nullptr;
    }
    if (!data->opData()) {
        return nullptr;
    }
    SkPicturePlayback playback(data);
    SkPictureRecorder r;
    playback.draw(r.beginRecording(info.fCullRect), nullptr/*no callback*/, buffer);
    return r.finishRecordingAsPicture();
}

sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream, const SkDeserialProcs* procs) {
    return MakeFromStream(stream, procs, nullptr);
}

sk_sp<SkPicture> SkPicture::MakeFromData(const void* data, size_t size,
                                         const SkDeserialProcs* procs) {
    if (!data) {
        return nullptr;
    }
    SkMemoryStream stream(data, size);
    return MakeFromStream(&stream, procs, nullptr);
}

sk_sp<SkPicture> SkPicture::MakeFromData(const SkData* data, const SkDeserialProcs* procs) {
    if (!data) {
        return nullptr;
    }
    SkMemoryStream stream(data->data(), data->size());
    return MakeFromStream(&stream, procs, nullptr);
}

sk_sp<SkPicture> SkPicture::MakeFromStream(SkStream* stream, const SkDeserialProcs* procsPtr,
                                           SkTypefacePlayback* typefaces) {
    SkPictInfo info;
    if (!StreamIsSKP(stream, &info)) {
        return nullptr;
    }

    SkDeserialProcs procs;
    if (procsPtr) {
        procs = *procsPtr;
    }

    uint8_t trailingStreamByteAfterPictInfo;
    if (!stream->readU8(&trailingStreamByteAfterPictInfo)) { return nullptr; }
    switch (trailingStreamByteAfterPictInfo) {
        case kPictureData_TrailingStreamByteAfterPictInfo: {
            std::unique_ptr<SkPictureData> data(
                    SkPictureData::CreateFromStream(stream, info, procs, typefaces));
            return Forwardport(info, data.get(), nullptr);
        }
        case kCustom_TrailingStreamByteAfterPictInfo: {
            int32_t ssize;
            if (!stream->readS32(&ssize) || ssize >= 0 || !procs.fPictureProc) {
                return nullptr;
            }
            size_t size = sk_negate_to_size_t(ssize);
            auto data = SkData::MakeUninitialized(size);
            if (stream->read(data->writable_data(), size) != size) {
                return nullptr;
            }
            return procs.fPictureProc(data->data(), size, procs.fPictureCtx);
        }
        default:    // fall through to error return
            break;
    }
    return nullptr;
}

sk_sp<SkPicture> SkPicturePriv::MakeFromBuffer(SkReadBuffer& buffer) {
    SkPictInfo info;
    if (!SkPicture::BufferIsSKP(&buffer, &info)) {
        return nullptr;
    }
    // size should be 0, 1, or negative
    int32_t ssize = buffer.read32();
    if (ssize < 0) {
        const SkDeserialProcs& procs = buffer.getDeserialProcs();
        if (!procs.fPictureProc) {
            return nullptr;
        }
        size_t size = sk_negate_to_size_t(ssize);
        return procs.fPictureProc(buffer.skip(size), size, procs.fPictureCtx);
    }
    if (ssize != 1) {
        // 1 is the magic 'size' that means SkPictureData follows
        return nullptr;
    }
   std::unique_ptr<SkPictureData> data(SkPictureData::CreateFromBuffer(buffer, info));
    return SkPicture::Forwardport(info, data.get(), &buffer);
}

SkPictureData* SkPicture::backport() const {
    SkPictInfo info = this->createHeader();
    SkPictureRecord rec(SkISize::Make(info.fCullRect.width(), info.fCullRect.height()), 0/*flags*/);
    rec.beginRecording();
        this->playback(&rec);
    rec.endRecording();
    return new SkPictureData(rec, info);
}

void SkPicture::serialize(SkWStream* stream, const SkSerialProcs* procs) const {
    this->serialize(stream, procs, nullptr);
}

sk_sp<SkData> SkPicture::serialize(const SkSerialProcs* procs) const {
    SkDynamicMemoryWStream stream;
    this->serialize(&stream, procs, nullptr);
    return stream.detachAsData();
}

static sk_sp<SkData> custom_serialize(const SkPicture* picture, const SkSerialProcs& procs) {
    if (procs.fPictureProc) {
        auto data = procs.fPictureProc(const_cast<SkPicture*>(picture), procs.fPictureCtx);
        if (data) {
            size_t size = data->size();
            if (!SkTFitsIn<int32_t>(size) || size <= 1) {
                return SkData::MakeEmpty();
            }
            return data;
        }
    }
    return nullptr;
}

static bool write_pad32(SkWStream* stream, const void* data, size_t size) {
    if (!stream->write(data, size)) {
        return false;
    }
    if (size & 3) {
        uint32_t zero = 0;
        return stream->write(&zero, 4 - (size & 3));
    }
    return true;
}

void SkPicture::serialize(SkWStream* stream, const SkSerialProcs* procsPtr,
                          SkRefCntSet* typefaceSet) const {
    SkSerialProcs procs;
    if (procsPtr) {
        procs = *procsPtr;
    }

    SkPictInfo info = this->createHeader();
    stream->write(&info, sizeof(info));

    if (auto custom = custom_serialize(this, procs)) {
        int32_t size = SkToS32(custom->size());
        if (size == 0) {
            stream->write8(kFailure_TrailingStreamByteAfterPictInfo);
            return;
        }
        stream->write8(kCustom_TrailingStreamByteAfterPictInfo);
        stream->write32(-size);    // negative for custom format
        write_pad32(stream, custom->data(), size);
        return;
    }

    std::unique_ptr<SkPictureData> data(this->backport());
    if (data) {
        stream->write8(kPictureData_TrailingStreamByteAfterPictInfo);
        data->serialize(stream, procs, typefaceSet);
    } else {
        stream->write8(kFailure_TrailingStreamByteAfterPictInfo);
    }
}

void SkPicturePriv::Flatten(const sk_sp<const SkPicture> picture, SkWriteBuffer& buffer) {
    SkPictInfo info = picture->createHeader();
    std::unique_ptr<SkPictureData> data(picture->backport());

    buffer.writeByteArray(&info.fMagic, sizeof(info.fMagic));
    buffer.writeUInt(info.getVersion());
    buffer.writeRect(info.fCullRect);

    if (auto custom = custom_serialize(picture.get(), buffer.fProcs)) {
        int32_t size = SkToS32(custom->size());
        buffer.write32(-size);    // negative for custom format
        buffer.writePad32(custom->data(), size);
        return;
    }

    if (data) {
        buffer.write32(1); // special size meaning SkPictureData
        data->flatten(buffer);
    } else {
        buffer.write32(0); // signal no content
    }
}

sk_sp<SkPicture> SkPicture::MakePlaceholder(SkRect cull) {
    struct Placeholder : public SkPicture {
          explicit Placeholder(SkRect cull) : fCull(cull) {}

          void playback(SkCanvas*, AbortCallback*) const override { }

          // approximateOpCount() needs to be greater than kMaxPictureOpsToUnrollInsteadOfRef
          // in SkCanvas.cpp to avoid that unrolling.  SK_MaxS32 can't not be big enough!
          int    approximateOpCount()   const override { return SK_MaxS32; }
          size_t approximateBytesUsed() const override { return sizeof(*this); }
          SkRect cullRect()             const override { return fCull; }

          SkRect fCull;
    };
    return sk_make_sp<Placeholder>(cull);
}
