@@ -306,6 +306,43 @@ static bool UpdateAtlasBitmap(const GlyphAtlas& atlas,
306306 return true ;
307307}
308308
309+ // The texture needs to be cleared to transparent black so that linearly
310+ // samplex rotated/skewed glyphs do not grab uninitialized data.
311+ bool ClearTextureToTransparentBlack (Context& context,
312+ HostBuffer& host_buffer,
313+ std::shared_ptr<CommandBuffer>& cmd_buffer,
314+ std::shared_ptr<BlitPass>& blit_pass,
315+ std::shared_ptr<Texture>& texture) {
316+ // The R8/A8 textures used for certain glyphs is not supported as color
317+ // attachments in most graphics drivers. To be safe, just do a CPU clear
318+ // for these.
319+ if (texture->GetTextureDescriptor ().format ==
320+ context.GetCapabilities ()->GetDefaultGlyphAtlasFormat ()) {
321+ size_t byte_size =
322+ texture->GetTextureDescriptor ().GetByteSizeOfBaseMipLevel ();
323+ BufferView buffer_view =
324+ host_buffer.Emplace (nullptr , byte_size, DefaultUniformAlignment ());
325+
326+ ::memset (buffer_view.buffer->OnGetContents () + buffer_view.range.offset, 0,
327+ byte_size);
328+ buffer_view.buffer->Flush ();
329+ return blit_pass->AddCopy (buffer_view, texture);
330+ }
331+ // In all other cases, we can use a render pass to clear to a transparent
332+ // color.
333+ ColorAttachment attachment;
334+ attachment.clear_color = Color::BlackTransparent();
335+ attachment.load_action = LoadAction::kClear ;
336+ attachment.store_action = StoreAction::kStore ;
337+ attachment.texture = texture;
338+
339+ RenderTarget render_target;
340+ render_target.SetColorAttachment (attachment, 0u );
341+
342+ auto render_pass = cmd_buffer->CreateRenderPass (render_target);
343+ return render_pass->EncodeCommands ();
344+ }
345+
309346std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas (
310347 Context& context,
311348 GlyphAtlas::Type type,
@@ -455,28 +492,18 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
455492 }
456493 descriptor.size = atlas_size;
457494 descriptor.storage_mode = StorageMode::kDevicePrivate ;
495+ descriptor.usage = TextureUsage::kShaderRead | TextureUsage::kRenderTarget ;
458496 new_texture = context.GetResourceAllocator ()->CreateTexture (descriptor);
459497 }
460498
461499 if (!new_texture) {
462500 return nullptr ;
463501 }
464- // The texture needs to be cleared to transparent black so that linearly
465- // samplex rotated/skewed glyphs do not grab uninitialized data. We could
466- // instead use a render pass to clear to transparent black, but there are
467- // more restrictions on what kinds of textures can be bound on GLES.
468- {
469- auto bytes =
470- new_texture->GetTextureDescriptor ().GetByteSizeOfBaseMipLevel ();
471- BufferView buffer_view =
472- host_buffer.Emplace (nullptr , bytes, DefaultUniformAlignment ());
473-
474- ::memset (buffer_view.buffer->OnGetContents () + buffer_view.range.offset, 0,
475- bytes);
476- blit_pass->AddCopy (buffer_view, new_texture);
477- }
478502
479503 new_texture->SetLabel (" GlyphAtlas" );
504+
505+ ClearTextureToTransparentBlack (context, host_buffer, cmd_buffer, blit_pass,
506+ new_texture);
480507 if (!UpdateAtlasBitmap (*glyph_atlas, blit_pass, host_buffer, new_texture,
481508 font_glyph_pairs)) {
482509 return nullptr ;
0 commit comments