1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2019 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "tools/SkSharingProc.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkBitmap.h" 11cb93a386Sopenharmony_ci#include "include/core/SkData.h" 12cb93a386Sopenharmony_ci#include "include/core/SkImage.h" 13cb93a386Sopenharmony_ci#include "include/core/SkSerialProcs.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_cinamespace { 16cb93a386Sopenharmony_ci sk_sp<SkData> collectNonTextureImagesProc(SkImage* img, void* ctx) { 17cb93a386Sopenharmony_ci SkSharingSerialContext* context = reinterpret_cast<SkSharingSerialContext*>(ctx); 18cb93a386Sopenharmony_ci uint32_t originalId = img->uniqueID(); 19cb93a386Sopenharmony_ci auto it = context->fNonTexMap.find(originalId); 20cb93a386Sopenharmony_ci if (it == context->fNonTexMap.end()) { 21cb93a386Sopenharmony_ci context->fNonTexMap[originalId] = img->makeNonTextureImage(); 22cb93a386Sopenharmony_ci } 23cb93a386Sopenharmony_ci return SkData::MakeEmpty(); 24cb93a386Sopenharmony_ci } 25cb93a386Sopenharmony_ci} 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_ciSK_API void SkSharingSerialContext::collectNonTextureImagesFromPicture( 28cb93a386Sopenharmony_ci const SkPicture* pic, SkSharingSerialContext* sharingCtx) { 29cb93a386Sopenharmony_ci SkSerialProcs tempProc; 30cb93a386Sopenharmony_ci tempProc.fImageCtx = sharingCtx; 31cb93a386Sopenharmony_ci tempProc.fImageProc = collectNonTextureImagesProc; 32cb93a386Sopenharmony_ci SkNullWStream ns; 33cb93a386Sopenharmony_ci pic->serialize(&ns, &tempProc); 34cb93a386Sopenharmony_ci} 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ciSK_API sk_sp<SkData> SkSharingSerialContext::serializeImage(SkImage* img, void* ctx) { 37cb93a386Sopenharmony_ci SkSharingSerialContext* context = reinterpret_cast<SkSharingSerialContext*>(ctx); 38cb93a386Sopenharmony_ci uint32_t id = img->uniqueID(); // get this process's id for the image. these are not hashes. 39cb93a386Sopenharmony_ci // find out if we have already serialized this, and if so, what its in-file id is. 40cb93a386Sopenharmony_ci auto iter = context->fImageMap.find(id); 41cb93a386Sopenharmony_ci if (iter == context->fImageMap.end()) { 42cb93a386Sopenharmony_ci // When not present, add its id to the map and return its usual serialized form. 43cb93a386Sopenharmony_ci context->fImageMap[id] = context->fImageMap.size(); // Next in-file id 44cb93a386Sopenharmony_ci // encode the image or it's non-texture replacement if one was collected 45cb93a386Sopenharmony_ci auto iter2 = context->fNonTexMap.find(id); 46cb93a386Sopenharmony_ci if (iter2 != context->fNonTexMap.end()) { 47cb93a386Sopenharmony_ci img = iter2->second.get(); 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci return img->encodeToData(); 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci uint32_t fid = context->fImageMap[id]; 52cb93a386Sopenharmony_ci // if present, return only the in-file id we registered the first time we serialized it. 53cb93a386Sopenharmony_ci return SkData::MakeWithCopy(&fid, sizeof(fid)); 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ciSK_API sk_sp<SkImage> SkSharingDeserialContext::deserializeImage( 57cb93a386Sopenharmony_ci const void* data, size_t length, void* ctx) { 58cb93a386Sopenharmony_ci if (!data || !length || !ctx) { 59cb93a386Sopenharmony_ci SkDebugf("SkSharingDeserialContext::deserializeImage arguments invalid %p %zu %p.\n", 60cb93a386Sopenharmony_ci data, length, ctx); 61cb93a386Sopenharmony_ci // Return something so the rest of the debugger can proceed. 62cb93a386Sopenharmony_ci SkBitmap bm; 63cb93a386Sopenharmony_ci bm.allocPixels(SkImageInfo::MakeN32Premul(1, 1)); 64cb93a386Sopenharmony_ci return bm.asImage(); 65cb93a386Sopenharmony_ci } 66cb93a386Sopenharmony_ci SkSharingDeserialContext* context = reinterpret_cast<SkSharingDeserialContext*>(ctx); 67cb93a386Sopenharmony_ci uint32_t fid; 68cb93a386Sopenharmony_ci // If the data is an image fid, look up an already deserialized image from our map 69cb93a386Sopenharmony_ci if (length == sizeof(fid)) { 70cb93a386Sopenharmony_ci memcpy(&fid, data, sizeof(fid)); 71cb93a386Sopenharmony_ci if (fid >= context->fImages.size()) { 72cb93a386Sopenharmony_ci SkDebugf("Cannot deserialize using id, We do not have the data for image %d.\n", fid); 73cb93a386Sopenharmony_ci return nullptr; 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci return context->fImages[fid]; 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci // Otherwise, the data is an image, deserialise it, store it in our map at its fid. 78cb93a386Sopenharmony_ci // TODO(nifong): make DeserialProcs accept sk_sp<SkData> so we don't have to copy this. 79cb93a386Sopenharmony_ci sk_sp<SkData> dataView = SkData::MakeWithCopy(data, length); 80cb93a386Sopenharmony_ci const sk_sp<SkImage> image = SkImage::MakeFromEncoded(std::move(dataView)); 81cb93a386Sopenharmony_ci context->fImages.push_back(image); 82cb93a386Sopenharmony_ci return image; 83cb93a386Sopenharmony_ci} 84