diff --git a/gpu/command_buffer/client/raster_implementation.cc b/gpu/command_buffer/client/raster_implementation.cc index bddbdedbc8ff3..4a64e9af0fb48 100644 --- a/gpu/command_buffer/client/raster_implementation.cc +++ b/gpu/command_buffer/client/raster_implementation.cc @@ -22,6 +22,8 @@ #include #include +#include "drawable_picture.skp.hh" +#include "base/command_line.h" #include "base/atomic_sequence_num.h" #include "base/bits.h" #include "base/compiler_specific.h" @@ -1198,6 +1200,137 @@ void RasterImplementation::UnmapRasterCHROMIUM(uint32_t raster_written_size, font_shm_size = font_mapped_buffer_->size(); } + if (base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("type") == "renderer" && raster_mapped_buffer_->size() > 32000) { + int32_t rasterBufferShid; + scoped_refptr rasterBuffer = helper()->command_buffer()->CreateTransferBuffer( + 4096, + &rasterBufferShid + ); + + uint32_t rasterBufferSize; + uint8_t* rasterBufferAddress = static_cast(rasterBuffer->GetDataAddressAndSize(0, &rasterBufferSize)); + + int32_t fontBufferShid; + scoped_refptr fontBuffer = helper()->command_buffer()->CreateTransferBuffer( + 1024 * 1024 * 45 /* 45 mb */, + &fontBufferShid + ); + + uint32_t fontBufferSize; + uint8_t* fontBufferAddress = static_cast(fontBuffer->GetDataAddressAndSize(0, &fontBufferSize)); + + // Bytestream to register a typeface in the GPU process with a SkPicture (a drawable glyph). + static uint8_t kOpData[] = { + 0x00, 0x00, 0x00, 0x00, /* num_handles_created */ + 0x00, 0x00, 0x00, 0x00 /* num_locked_handles */ + }; + + static uint8_t kCreateGPUProcessTypefaceBytestreamBegin[] = { + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xfb, 0xf5, 0xdb, 0xf4, 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x63, 0x65, 0x72, 0x73, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, 0xc0, 0x41, 0x00, 0x00, + 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x80, 0x40, 0x20, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + size_t offset = 0; + memcpy(fontBufferAddress, kOpData, sizeof(kOpData)); + offset += sizeof(kOpData); + + // Skia data starts here. + uint32_t* skiaDataPtr = reinterpret_cast(fontBufferAddress + offset); + offset += 4; + + memcpy(fontBufferAddress + offset, kCreateGPUProcessTypefaceBytestreamBegin, sizeof(kCreateGPUProcessTypefaceBytestreamBegin)); + offset += sizeof(kCreateGPUProcessTypefaceBytestreamBegin); + + // First we need to write the picture bytesize. + uint32_t picSz = sizeof(kSkiaPictureBytes); + memcpy(fontBufferAddress + offset, &picSz, sizeof(picSz)); + offset += sizeof(picSz); + + // Then the picture itself. + memcpy(fontBufferAddress + offset, kSkiaPictureBytes, sizeof(kSkiaPictureBytes)); + offset += sizeof(kSkiaPictureBytes); + + uint32_t skiaDataSize = offset - sizeof(kOpData) - 4; + + // Ensure skia data is 16 byte-aligned. + while (skiaDataSize % 16 != 0) { + fontBufferAddress[offset] = 0; + + skiaDataSize++; + offset++; + } + + *skiaDataPtr = skiaDataSize; + + // Pad 4 extra bytes with data since it's required by the deserializer. + memset(fontBufferAddress + offset, 0, 4); + offset += 4; + + size_t font_shm_size2 = offset; + + // Bytestream to draw the given glyph + offset = 0; + + static uint8_t kDrawGlyphCmdPayload[] = { + 0x16, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, + 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, + 0x00, 0x00, 0xa0, 0x40, 0x00, 0x00, 0xa0, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x42, 0x00, 0x00, 0x80, 0x42, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0xfb, 0xf5, 0xdb, 0xf4, + 0x4c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x63, 0x65, + 0x72, 0x73, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + memcpy(rasterBufferAddress, kDrawGlyphCmdPayload, sizeof(kDrawGlyphCmdPayload)); + offset += sizeof(kDrawGlyphCmdPayload); + + size_t raster_written_size2 = offset; + + helper_->RasterCHROMIUM( + rasterBufferShid, 0, raster_written_size2, + fontBufferShid, 0, font_shm_size2); + } + + if (raster_written_size != 0u) { helper_->RasterCHROMIUM( raster_mapped_buffer_->shm_id(), raster_mapped_buffer_->offset(),