Como o Photoshop resolveu o trabalho com arquivos maiores que couberem na memória

Saiba como a Adobe conseguiu permitir que os usuários editassem até mesmo os maiores arquivos na versão Web do seu icônico app Photoshop.

Introdução

Este artigo também está disponível na forma de vídeo.

Em 2021, a Adobe e a engenharia do Chrome lançaram uma versão do Photoshop na Web (em inglês). O software faz uso inovador do WebAssembly com recursos como SIMD, armazenamento de alto desempenho no sistema de arquivos particular de origem, o espaço de cores P3 para canvas e Web Components com Lit. Neste artigo, queremos nos concentrar em como a engenharia do Adobe Photoshop resolveu o trabalho com arquivos maiores que a memória. E, no caso do WebAssembly, como o Photoshop funciona com arquivos maiores que o espaço de endereço de 32 bits do wasm32.

O app Photoshop enquanto edita uma imagem do logotipo do Projeto Fugu.

O problema

Abrir um arquivo para edição requer uma grande quantidade de memória, muito mais do que abrir o arquivo para visualização. Os arquivos editados no Photoshop geralmente exigem mais memória do que o disponível no dispositivo pelo usuário devido aos muitos recursos oferecidos pelo software, aos tipos de design e edição digital para os quais ele é usado e aos recursos dos dispositivos dos usuários.

O formato de arquivo do Photoshop armazena dados com compactação sem perdas. Quando um arquivo ou documento é lido, todos os dados da imagem são descompactados para permitir um processamento mais eficiente. Como resultado, a quantidade de memória necessária pode ser várias vezes maior do que a quantidade de espaço que um documento usa no disco ou no armazenamento em nuvem.

O Photoshop oferece suporte a um histórico muito amplo de desfazer. Muitas operações no Photoshop são o que chamamos de operações destrutivas. Ou seja, fazer edições (por exemplo, pintar com um pincel) resultará em novos dados de pixel, que podem ser tão grandes quanto os dados originais. Fazer essas edições em uma sessão de edição longa resulta em grandes quantidades de dados de pixel que devem ser mantidos por perto para possibilitar as operações de desfazer. Assim, o histórico pode chegar a várias centenas de megabytes ou muitos gigabytes de dados.

Dispositivos e plataformas, sejam computadores desktop, dispositivos móveis ou navegadores, todos gerenciam a memória. Alguns são mais generosos que outros em relação à quantidade de memória que disponibilizam para os aplicativos. A quantidade de memória também varia de acordo com o dispositivo, como você sabe quando compra um novo computador ou dispositivo e especifica a quantidade desejada de memória de acesso aleatório (RAM). Muitas dessas plataformas também são compatíveis com memória virtual, o que permite que um aplicativo use mais memória do que a disponível fisicamente. Esse suporte varia de acordo com o sistema operacional e o tempo de execução, como no caso do WebAssembly, pode não ser facilmente acessível ou utilizável pelos aplicativos. Além disso, os sistemas virtuais modernos têm limites superiores que são facilmente excedidos pelos requisitos do Photoshop.

O ideal é que os aplicativos usem a quantidade de memória necessária. Isso geralmente permite oferecer o melhor desempenho aos usuários. No entanto, se usarem muita memória, podem ser penalizados pela plataforma de tempo de execução ou ficar sem memória, resultando em falhas.

Como uma observação histórica, o problema original que o Photoshop precisava resolver era a edição de arquivos de resolução de impressão nas primeiras versões do macOS, de apenas 1 MB para o SO e todos os aplicativos. Uma imagem de página inteira de 300 dpi em CMYK tem aproximadamente 32 MB não compactada.

A solução

Para resolver o problema do aplicativo exceder a quantidade de RAM disponível, o Photoshop implementou um sistema de memória virtual (VM) de software. O Photoshop usa sua VM para gerenciar dados de documentos, especialmente dados de imagem, todo o histórico e estado de desfazer, bem como o armazenamento de trabalho para o comando atual. Ele também é usado para armazenar grandes blocos de dados em cache, como descrições de pincéis, para que eles só precisem ser serializados no disco uma vez.

Como exemplo de um dos aspectos gerenciados pela VM, os dados de imagem são armazenados usando uma representação de mipmap, que é um conjunto piramidal de blocos que fornece dados de imagem em um intervalo de resoluções baixa a alta. Isso permite que o Photoshop opere com os dados de resolução apropriados para ter uma resposta mais rápida quando o zoom for aumentado ou ao olhar para uma visualização, em vez de diminuir o zoom.

Exemplo de armazenamento de imagens de mipmap: a imagem principal à esquerda é acompanhada por cópias filtradas de tamanho reduzido.

Durante a inicialização do aplicativo, o Photoshop determina a quantidade de RAM disponível. Ele reserva uma parte para os dados serem armazenados na VM. A RAM restante está disponível para outros aplicativos usando a biblioteca C++ de tempo de execução padrão. A memória da VM é dividida em páginas. Normalmente, cada página é um múltiplo do tamanho da página de hardware do dispositivo. Quando usada para dados de imagem, a memória é referenciada como blocos. Um bloco é uma área quadrada de pixels de uma única camada, incluindo limites geométricos. Um bloco consome uma ou mais páginas.

O Photoshop cria um ou mais arquivos de rascunho para fornecer suporte baseado em disco para páginas de VM. Esses arquivos de rascunho são armazenados no sistema de arquivos particular de origem. A captura de tela mostra um exemplo de hierarquia de arquivos com um arquivo de rascunho (destacado em amarelo) e outros arquivos durante uma sessão de edição de imagens. Cada arquivo de rascunho pode conter várias páginas de VM. Quando a VM precisa de mais apoio, ela cria outros arquivos de rascunho. À medida que as páginas são liberadas, o espaço delas em um arquivo de rascunho pode ser reutilizado em novas páginas.

Inspecionando a hierarquia de arquivos do sistema de arquivos particulares de origem do Photoshop com a extensão OPFS Explorer do Chrome.

Ao processar dados de imagem, o Photoshop faz a iteração dos blocos, realizando cálculos de pixels. Cada cálculo pode fazer referência a vários blocos. A VM é responsável por garantir que os blocos de origem e destino da iteração atual estejam na memória, carregando-os dos arquivos iniciais conforme necessário. Ao mesmo tempo, ele pode transferir as páginas para os arquivos de rascunho para liberar espaço na memória.

Conclusões

Embora os detalhes concretos da implementação da VM vão muito além do escopo deste documento (e também são de propriedade da Adobe), com a descrição de alto nível da solução, você pode entender como o Photoshop lida com arquivos grandes. O sistema de arquivos particular de origem, com alto desempenho no acesso de leitura e gravação aos arquivos, é um componente essencial da solução.

Agradecimentos

Esta postagem do blog foi revisada por Oliver Unter Ecker e Rachel Andrew. Um agradecimento especial a Russell Williams por sua excelente documentação sobre a VM do Photoshop.