holodepth

HTML5 Canvas · 2D–WebGL köprüsü

İş hattı farkları: Canvas 2D yorumlaması ile WebGL gönderim modeli

Grafik iş hattı ( render pipeline ), ham veriden ekranda bir kare oluşmasına kadar giden aşamaların düşünsel sırasıdır. Canvas 2D ve WebGL aynı piksel dünyasına hizmet eder; fakat birinde çoğu zaman üst düzey komutlar yorumlanır, diğerinde ise tamponlar ve gölgelendirici programları ile donanım yolu daha açıkça adreslenir. Bu sayfa Canvas geliştiricisi için «aynı kelimeyi ( çizim ) kullanıyorum ama alt katman nasıl ayrılıyor?» sorusuna yanıt verir — tam WebGL veya GLSL kursu değildir.

Rol dağılımı özeti CPU işlemesi ve GPU işlemesi; API’nın kenarları Canvas limitleri; geçiş gerekçesi Neden WebGL?. Piksel ve bağlam bütçesi Yeniden çizim maliyeti ile ölçülür — burada tekrar piksel reçetesi yazılmaz.

Özet: iki yüzey, iki iş ritmi

Aşama fikri Canvas 2D düşüncesi WebGL düşüncesi
Girdi hazırlığı Komut + bağlam durumu Tampon + gölgelendirici girdileri
Çekirdek iş Dahili raster ( uygulamaya bağlı) Köşe → raster → piksel aşamaları
Çizim kontrolü Çizim sırası ve stil Durum makinesi ve gönderim

İş hattı kavramı ve soyutlama düzeyi

İş hattını düşünmenin amacı, bir üründe «hangi katmanın ne zaman çalıştığını» ortak bir dile çevirmektir: güncelleme mantığı ( CPU ), çizim çağrıları, ardından tarayıcı ve işletim sistemi bileşimi ile ekrana sunum. Canvas 2D ve WebGL’de bu sıranın görünür ve mühendislik edilebilir kısımları farklıdır — ikinci dünya daha fazla açık halde GPU fazlarına yaklaştırır. Aynı üst başlıkta kalsa bile, örneğin «çizim» fazının içinde Canvas’ta yalnız komut listesi görünürken WebGL’de tampon yükleme + durum + gönderim alt adımları ayrı kayıt altına alınır; bu ayrım hata ayıklama dilinizi belirler.

Köprü okuyucusu için uyarı: her iki API’nın iç uygulaması tarayıcıya göre değişebilir ( implementation-defined ). Bu yüzden mikrodüzeyde «kesin olarak şu sırada şu register» yerine ürün kararı ve profil üzerinden doğrulama önerilir. Bu sayfa zihinsel model sunar; donanım kılavuzu değildir. Modeli takım içinde paylaşmak için kısa bir iç terim listesi ( «güncelleme», «üretim ( render )», «sunum» ) yeterlidir — faz isimleri projede özelleşebilir, önemli olan herkesin aynı hiyerarşide konuşmasıdır ( 5. bölüm ).

Uygulama içinde sık sık hem Canvas hem WebGL kullanıldığında ( hybrid ), iki iş ritminin çakışmaması için kare fazları yazılı olarak sabitlenmelidir — Neden WebGL · hibrit düzen ile uyumludur. Aksi halde biri diğerinin üzerine geç çizilir, giriş olayları yanlış katmana düşer veya bellekte çift tampon politikasını şişirirsiniz — sorun çoğu zaman API değil, faz sözleşmesinin yazılmamış olmasıdır.

Canvas 2D yorumlayıcı modeli ve görünür fazlar

Tipik akış: JavaScript güncelleme ve çizim bölümünü çalıştırır; siz stroke, fill, drawImage gibi komutlar gönderirsiniz. Tarayıcı bu komutları içte kaydedebilir, birleştirilebilir veya doğrudan raster alt sistemine iletebilir — dışarıdan tek bir «vertex shader yazıyorum» yüzü görmeyebilirsiniz. Bu üst düzey soyutlama, prototiplemeyi hızlandırır; fakat darboğazı «hangi faz» olarak etiketlemek için araçlar daha dolaylıdır. Zihinsel çözüm: tarayıcının içerde bir «bekleyen çizim kaydı» tuttuğunu düşünün; siz sırayla komut yazarsınız, motor ise bunları ertelenmiş biçimde birleştirebilir — bu yüzden profilde «ben şu anda tam olarak hangi fazdayım?» sorusunun cevabı bazen tek satır etiket olarak görünmez.

Canvas bağlamının sürekli durumu ( dönüşüm matrisi, dolgu rengi, birleştirme modu ) iş hattının giriş konfigürasyonu gibidir — WebGL’deki durum makinesine uzaktan benzer, fakat geometri paketleme yerine komut akışı ile ifade edilir. 2D bağlam düşüncesiyle birlikte okunmalıdır. Pratikte her kare başında bileşik iş üretmek yerine, hangi alanların «bu karede değişti» olduğunu bilmek ( yeniden çizim bayrağı ) çizim hattının üstünde ayrı bir optimizasyon katmanıdır — iş hattı düşüncesiyle çelişmez, tamamlar.

Aşağıdaki çizelge öğreticidir; bağlam oluşturmaz. Üretimde aşama sürelerini gerçek zaman ölçümü ile doğrulayın. Komut sayısı arttıkça, aynı çizelgenin üçüncü satırının ( arka uç raster ) süresi baskın hale gelebilir — o zaman batching ve offscreen gibi ürün kararları devreye girer ( bu sayfada yalnız köprü işaretlenir ).

/** Öğretici faz sırası — süre ölçümü uygulamaya özgüdür. */
export const CANVAS2D_FRAME_PHASES = Object.freeze([
  { id: 'simulate_or_animate', owner: 'cpu', summary: 'Oyun / görselleştirme mantığı' },
  { id: 'prepare_paths_or_layers', owner: 'cpu', summary: 'beginPath, katman seçimi' },
  { id: 'issue_draw_ops', owner: 'cpu', summary: 'fill, stroke, drawImage, ...' },
  {
    id: 'backend_raster_and_composite',
    owner: 'mixed',
    summary: 'Tarayıcı raster ve bileşim (uygulamaya bağlı)',
  },
]);

WebGL gönderim yolu ve gölgelendirici fazları

WebGL tarafında iş hattı klasik GPU düşüncesine yaklaşır: köşe verisi tamponlardan okunur, köşe gölgelendirici çalışır, primitive raster edilir, piksel ( fragment ) gölgelendirici çalışır, birleştirme ve derinlik kuralları uygulanır. Çizim çağrısı ( draw call ) bu yolu tetikler; çağrıdan önce CPU durumu ( program, bağlayıcı tamponlar, birleştirme ayarı ) hazır olmalıdır. Tek bir draw call çağrısı, bu hazırlığın «tamam» sinyali gibidir: hazır değilken göndermek ya hiç çizmez ya da eski durumla çizer — Canvas’taki «yanlış fillStyle ile devam ettim» hatasının daha sert yüzünü hatırlatır.

Köprü farkı: Canvas 2D’de bu fazların çoğu soyuttur; WebGL’de ise gölgelendirici kaynağı ve tampon bağları doğrudan sizin sorumluluğunuzdadır ( veya bir motorun ). Bu «görünürlük» bakım maliyetini artırır; sahne karmaşıksa karşılığı tam kontrol ve ölçeklenebilir paralelliktir. Neden WebGL · programlanabilir boru hattı ile örtüşür — burada shader kodu öğretilmez. Çok geçişli ( multi-pass ) düzenlerde aynı kare içinde bu çizelgenin birden çok turu işletilir; her turda hedef tampon ve birleştirme kuralları yeniden düşünülmelidir — zaman çizelgesi ile birlikte planlanır.

Aşağıdaki çizelge soyutlamayı sabitler; gerçek uygulamada ek aşamalar ( örnekleme genişletme, çoklu hedef tampon ) olabilir. Çizelgeyi ezberlemekten çok, «CPU’da neyi bitirip GPU’ya ne zaman bıraktığımı» cümlesiyle ekibinize anlatmayı hedefleyin.

/** Soyut WebGL gönderim sırası — kursta genişletilir. */
export const WEBGL_FRAME_PHASES = Object.freeze([
  { id: 'cpu_upload_buffers', owner: 'cpu', summary: 'Vertex / indeks / uniform güncellemesi' },
  { id: 'cpu_set_state', owner: 'cpu', summary: 'Program, VA bağları, derinlik / stencil testleri' },
  { id: 'cpu_draw_dispatch', owner: 'cpu', summary: 'drawArrays / drawElements çağrısı' },
  { id: 'gpu_vertex_stage', owner: 'gpu', summary: 'Köşe gölgelendiricisi' },
  { id: 'gpu_raster', owner: 'gpu', summary: 'Primitive raster (örnekleyici)' },
  { id: 'gpu_fragment_stage', owner: 'gpu', summary: 'Piksel gölgelendiricisi + birleştirme' },
]);

Veri hazırlığı: komut akışı ile tampon paketleme

Canvas 2D’de «veri» çoğu zaman çizim komutlarıyla birlikte akar: yollar oluşturulur, görseller çekilir, durum alanları güncellenir. WebGL’de ise geometri genelde önceden paketlenmiş tamponlarda durur; kare içinde yapılan iş çoğu zaman küçük parametre güncellemesi + gönderim olmayı hedefler. Bu fark, üretim kodunun mimarisini doğrudan etkiler: WebGL tarafında veri düzenine ( interleaved öznitelikler, indeks paylaşımı ) yatırım yapılır; Canvas tarafında ise daha sık komut düzeni ( batching ) öne çıkar. Canvas tarafında da geometri anlık üretilebilir; fakat bellek üzerinde tutulan yol veya sprite listesi, WebGL’deki vertex tamponu ile aynı «hazırlık önceliği» rolünü paylaşır — fark, birinde sık sık API çağrısı, diğerinde sık sık bayt düzenidir.

Okuma geri senkronu ( readback ) her iki dünyada da iş hattını kesintiye uğratabilir — Canvas’ta sık getImageData, WebGL’de sık readPixels. Köprü tasarımında veriyi mümkün olduğunca GPU tarafında tutmak ortak hedef olmalıdır. CPU/GPU · geri okuma başlığına bağlanır. Okuma gereken iş akışları ( örneğin görüntü analizi ) çizim döngüsünden ayırıp düşük frekanslı karede çalıştırmak, iş hattını tek kanaldan çıkarmaya yardım eder.

Aşağıdaki yardımcı saf fonksiyondur; hangi yüzeyde hazırlığın daha görünür olduğunu tartışma listesi olarak döndürür — bağlam açmaz. Dönen metinleri tek başına karar sanmayın; üretimde profil ve gerçek ölçüm birincil kaynaktır ( 6. bölüm ).

/**
 * Hangi yüzeyde hangi hazırlığın öne çıktığını özetler (
 * kesin profil değildir ).
 * @param {'canvas2d'|'webgl'} surface
 */
export function summarizeDataPrepTouchpoints(surface) {
  const key = String(surface || '').toLowerCase();

  if (key === 'canvas2d') {
    return {
      emphasis: [
        'Çizim komutları ve bağlam durumu sıklığı',
        'Yol ve görsel kaynakları üzerinden veri akışı',
      ],
      typicalGpuVisibility: 'Raster alt sistemi uygulamaya bağlı soyutlanır',
    };
  }

  if (key === 'webgl') {
    return {
      emphasis: [
        'Tampon yerleşimi ve öznitelik bağları',
        'Durum makinesi + gönderim sıklığı',
      ],
      typicalGpuVisibility: 'Köşe ve piksel fazları doğrudan programlanır',
    };
  }

  return {
    emphasis: [],
    typicalGpuVisibility: 'bilinmeyen yüzey anahtarı',
  };
}

Kare zaman çizelgesi: güncelleme, çizim ve sunum

Çoğu etkileşimli uygulama döngüsünde önce dünya durumu güncellenir, sonra çizilir, en son tarayıcı birleştirir ve görüntüler. Canvas 2D ve WebGL için sıra aynı üst başlıkta kalır; fark, ikinci aşamanın iç yapısıdır. WebGL ile çoklu geçiş ( pass ) veya tampon hedefi değişimi sık görülür; Canvas 2D’de ise katman veya offscreen tamponlar ile benzer hiyerarşi kurulabilir — API ifadesi farklıdır. Aynı karede önce WebGL dünya tamponuna, sonra üstte şeffaf Canvas ile arayüz çizmek gibi desenlerde hangi yüzeyin hangi döngü adımında temizlendiği yazılmalıdır; aksi halde önceki karenin artığı üst üste biner.

Update vs render ve kare yönetimi bu zaman çizelgesinin üst omurgasıdır — iş hattı farkları aynı omurgaya oturur. requestAnimationFrame ile tetiklenen döngüde, animasyon düşünülse bile güncelleme ve çizim ayrımı korunursa profilde uzun JavaScript görevi ile çizim fazı birbirine karışmaz — bu ayrım köprü fazlarını planlamayı kolaylaştırır.

Sunum aşaması ( compositing, tarayıcı düzeni ) geliştirici kodundan görünmez olabilir fakat kare süresine katılır; özellikle karmaşık DOM ve filtreler ile birlikte kullanıldığında profilde ana iş parçacığı veya bileşim satırında görülür — tam GPU iş hattı değildir, yine de köprü tasarımında hesaba katılmalıdır. Tuvalin kendisi basit olsa bile sayfa genelinde ağır stil, kaydırma veya dönüşüm animasyonlarının çiziminize ek süre yazabileceğini unutmayın.

Ölçüm ve fazların ayırt edilmesi

Performans panelinde «anında» iş hattı diyagramı görmek her zaman mümkün olmayabilir; fakat süre harcamalarını kabaca ayırmak mümkündür: uzun JS görevleri güncelleme fazına, yoğun raster süresi çizim fazına, ani beklemeler bazen geri okuma veya kaynak yeniden boyutuna işaret eder. Canvas ve WebGL için etiketler farklı görünse de soru aynıdır: hangi faz bütçeyi yiyor? Şüphede kaldığınızda aynı sahneyi tek bir değişiklikle ( örneğin bir geçişi kapatmak veya çağrıyı birleştirmek ) ikiye bölüp kayıt almak; fark genelde hangi hattın daraldığını gösterir.

Bu sayfa FPS matematiği veya motor profili kursu vermez — Byteomi performans başlıklarına köprü bırakılır; yeniden çizim maliyeti ve toplama üzerinden faz ayrımı zaten pratikte işlenir. Köprü kullanıcısı için pratik: iş hattı düşüncesini önce kavramsallaştırın (1, 5 ), sonra tek tek fazları ölçümle doğrulayın.

WebGL geçişinde ilk haftalar çoğu zaman «durum ve tampon» fazında zaman kaybedilir; Canvas kökenli ekip için bu normaldir — program bağlama, öznitelik konumu, bağlama ve çizim öncesi küçük ayarlar profilde dağınık JavaScript süresi gibi görünebilir; iş hattı soyutlaması bu gürültüyü pratikte öğrenerek sadeleşir.

Köprü özeti, tuzaklar ve kontrol listesi

Canvas 2D iş hattı üst düzey komutlar üzerinden düşünülür; WebGL iş hattı gönderim ve gölgelendirici fazları üzerinden düşünülür. Köprü, iki düşünceyi aynı kare zaman çizelgesinde uzlaştırmayı gerektirir — özellikle hibrit ürünlerde faz sırası yazılı olmalıdır ( zaman çizelgesi ). İki API için aynı karede «önce ne güncellenir, hangi bağlam açılır, hangi yüzey temizlenir» sorusunun cevabı ekip içi sözleşme olmadan kolayca kaybolur.

Tuzaklar: WebGL’yi her çağrının otomatik olarak hafif olduğunu sanarak Canvas komutları gibi düşünmek; Canvas’ı arka planda tek tek GPU fazlarına eşleyebileceğinizi varsayarak WebGL kadar şeffaf sanmak; geri okumayı iki dünyada da hafife almak; tuval dışında kalan tarayıcı bileşim maliyetini görmezden gelmek. Canvas limitleri API kenarlarını, Neden WebGL? geçiş gerekçesini tamamlar.

Bu sayfanın sınırı

Donanım özelinde kayıt düzeyi ( register-level ) iş hattı, WebGPU ayrıntıları ve Three.js dahili sırası burada işlenmez. Odak: Canvas kökenli okuyucunun WebGL gönderim modeline geçerken ihtiyaç duyduğu düşünsel karşılaştırmadır.

  • Karenin güncelleme ve çizim fazları kodda ayrılmış mı?
  • Canvas tarafında komut sırası ve stil sıçraması kontrol altında mı?
  • WebGL tarafında tampon ve durum hazırlığı gönderimden önce tamamlanıyor mu?
  • Geri okuma noktaları bilinçli ve seyrek mi?
  • Tarayıcı bileşimi için makul bir üst süre varsayımı var mı?