आइए, मुख्य डेटा स्ट्रक्चर पर नज़र डालें. ये रेंडरिंग पाइपलाइन के इनपुट और आउटपुट होते हैं.
ये डेटा स्ट्रक्चर हैं:
- फ़्रेम ट्री, लोकल और रिमोट नोड से बने होते हैं. इनसे पता चलता है कि कौनसे वेब दस्तावेज़ किस रेंडर प्रोसेस और किस Blink रेंडरर में हैं.
- इम्यूटेबल फ़्रैगमेंट ट्री, लेआउट कंस्ट्रेंट एल्गोरिदम का आउटपुट और इनपुट दिखाता है.
- प्रॉपर्टी ट्री, किसी वेब दस्तावेज़ के ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, और स्क्रोल हैरारकी को दिखाते हैं. इनका इस्तेमाल पूरी पाइपलाइन में किया जाता है.
- डिसप्ले लिस्ट और पेंट चंक, रेस्टर और लेयराइज़ेशन एल्गोरिदम के इनपुट होते हैं.
- कंपोज़िटर फ़्रेम, जीपीयू का इस्तेमाल करके ड्रॉ करने के लिए इस्तेमाल की जाने वाली सरफ़ेस, रेंडर सर्फ़ेस, और जीपीयू टेक्सचर टाइल को एनकैप्सुलेट करते हैं.
इन डेटा स्ट्रक्चर के बारे में जानने से पहले, यहां दिया गया उदाहरण आर्किटेक्चर की समीक्षा के एक उदाहरण पर आधारित है. इस उदाहरण का इस्तेमाल इस दस्तावेज़ में किया गया है. साथ ही, यह भी बताया गया है कि डेटा स्ट्रक्चर इस पर कैसे लागू होते हैं.
<!-- Example code -->
<html>
<div style="overflow: hidden; width: 100px; height: 100px;">
<iframe style="filter: blur(3px);
transform: rotateZ(1deg);
width: 100px; height: 300px"
id="one" src="foo.com/etc"></iframe>
</div>
<iframe style="top:200px;
transform: scale(1.1) translateX(200px)"
id="two" src="bar.com"></iframe>
</html>
पेड़ों को फ़्रेम में डालना
Chrome कभी-कभी, क्रॉस-ऑरिजिन फ़्रेम को अपने पैरंट फ़्रेम से अलग रेंडर प्रोसेस में रेंडर कर सकता है.
उदाहरण के तौर पर दिए गए कोड में, कुल तीन फ़्रेम हैं:
साइट आइसोलेशन की सुविधा के साथ, Chromium इस वेब पेज को रेंडर करने के लिए, दो रेंडर प्रोसेस का इस्तेमाल करता है. उस वेब पेज के लिए, रेंडर करने की हर प्रोसेस में फ़्रेम ट्री को अपने अलग तरीके से दिखाया जाता है:
किसी दूसरी प्रोसेस में रेंडर किए गए फ़्रेम को रिमोट फ़्रेम के तौर पर दिखाया जाता है. रिमोट फ़्रेम में वह कम से कम जानकारी होती है जो रेंडरिंग के दौरान प्लेसहोल्डर के तौर पर काम करने के लिए ज़रूरी होती है. उदाहरण के लिए, इसका डाइमेंशन. अगर ऐसा नहीं किया जाता है, तो रिमोट फ़्रेम में अपने असल कॉन्टेंट को रेंडर करने के लिए ज़रूरी जानकारी नहीं होती.
वहीं दूसरी ओर, लोकल फ़्रेम एक ऐसा फ़्रेम दिखाता है जो स्टैंडर्ड रेंडरिंग पाइपलाइन से गुज़रता है. लोकल फ़्रेम में, उस फ़्रेम के डेटा (जैसे, डीओएम ट्री और स्टाइल डेटा) को रेंडर और दिखाए जाने लायक बनाने के लिए ज़रूरी सारी जानकारी होती है.
रेंडरिंग पाइपलाइन, लोकल फ़्रेम ट्री फ़्रैगमेंट की बारीकी के हिसाब से काम करती है.
मुख्य फ़्रेम के तौर पर foo.com
को एक पेचीदा उदाहरण से समझें:
<iframe src="bar.com"></iframe>
और यह bar.com
सबफ़्रेम:
<iframe src="foo.com/etc"></iframe>
हालांकि, अब भी सिर्फ़ दो रेंडरर हैं, लेकिन अब भी लोकल फ़्रेम ट्री के तीन फ़्रैगमेंट हैं. इनमें से दो, foo.com
के लिए रेंडर करने की प्रोसेस में और एक bar.com
के लिए रेंडर करने की प्रोसेस में है:
वेब पेज के लिए एक कंपोजिट फ़्रेम बनाने के लिए, Viz एक साथ तीनों लोकल फ़्रेम ट्री के रूट फ़्रेम से कंपोजिट फ़्रेम का अनुरोध करता है. इसके बाद, उन्हें एग्रीगेट करता है. कंपोज़र फ़्रेम सेक्शन भी देखें.
foo.com
का मुख्य फ़्रेम और foo.com/other-page
सबफ़्रेम, एक ही फ़्रेम ट्री का हिस्सा हैं और एक ही प्रोसेस में रेंडर किए गए हैं.
हालांकि, दोनों फ़्रेम के दस्तावेज़ के लाइफ़साइकल अलग-अलग होते हैं, क्योंकि वे अलग-अलग लोकल फ़्रेम ट्री फ़्रैगमेंट का हिस्सा होते हैं.
इस वजह से, एक अपडेट में दोनों के लिए एक कंपोज़िटर फ़्रेम जनरेट करना मुमकिन नहीं है.
रेंडर करने की प्रोसेस में, foo.com/other-page
के लिए जनरेट किए गए कंपोज़िटर फ़्रेम को सीधे foo.com
के मुख्य फ़्रेम के कंपोज़िटर फ़्रेम में कंपोज़ करने के लिए ज़रूरी जानकारी मौजूद नहीं है.
उदाहरण के लिए, प्रोसेस से बाहर का bar.com
पैरंट फ़्रेम, foo.com/other-url
iframe के डिसप्ले पर असर डाल सकता है. ऐसा, सीएसएस की मदद से iframe को बदलकर या उसके DOM में मौजूद दूसरे एलिमेंट से iframe के कुछ हिस्सों को छिपाकर किया जा सकता है.
विज़ुअल प्रॉपर्टी अपडेट करने वाला वॉटरफ़ॉल
डिवाइस स्केल फ़ैक्टर और व्यूपोर्ट साइज़ जैसी विज़ुअल प्रॉपर्टी, रेंडर किए गए आउटपुट पर असर डालती हैं. साथ ही, इन्हें लोकल फ़्रेम ट्री फ़्रैगमेंट के बीच सिंक किया जाना चाहिए. हर लोकल फ़्रेम ट्री फ़्रैगमेंट के रूट में, एक विजेट ऑब्जेक्ट जुड़ा होता है. विज़ुअल प्रॉपर्टी के अपडेट, सबसे ऊपर से सबसे नीचे तक बाकी विजेट में भेजे जाने से पहले, मुख्य फ़्रेम के विजेट में जाते हैं.
उदाहरण के लिए, जब व्यूपोर्ट का साइज़ बदलता है:
यह प्रोसेस तुरंत नहीं होती. इसलिए, डुप्लीकेट की गई विज़ुअल प्रॉपर्टी में सिंक टोकन भी शामिल होता है. विज़ कंपोजर इस सिंक टोकन का इस्तेमाल करके, सभी लोकल फ़्रेम ट्री फ़्रैगमेंट के इंतज़ार करता है, ताकि मौजूदा सिंक टोकन के साथ कंपोजर फ़्रेम सबमिट किया जा सके. इस प्रोसेस से, कॉम्पोज़िटर फ़्रेम को अलग-अलग विज़ुअल प्रॉपर्टी के साथ मिक्स होने से रोका जाता है.
इम्यूटेबल फ़्रैगमेंट ट्री
बदलाव न किए जा सकने वाला फ़्रैगमेंट ट्री, रेंडरिंग पाइपलाइन के लेआउट चरण का आउटपुट होता है. यह पेज पर मौजूद सभी एलिमेंट की पोज़िशन और साइज़ दिखाता है. (बदलाव लागू किए बिना).
हर फ़्रैगमेंट, किसी DOM एलिमेंट के हिस्से को दिखाता है. आम तौर पर, हर एलिमेंट में सिर्फ़ एक फ़्रैगमेंट होता है. हालांकि, प्रिंट करते समय इसे अलग-अलग पेजों में बांटने या एक से ज़्यादा कॉलम वाले कॉन्टेक्स्ट में कॉलम में बांटने पर और भी फ़्रैगमेंट हो सकते हैं.
लेआउट के बाद, हर फ़्रैगमेंट में बदलाव नहीं किया जा सकता. अहम बात यह है कि हम कुछ और पाबंदियां भी लगाते हैं. हम ये काम नहीं करते हैं:
- ट्री में किसी भी "अप" रेफ़रंस की अनुमति दें. (बच्चे अपने पैरंट के लिए पॉइंटर नहीं रख सकते.)
- पेड़ से नीचे का "बबल" डेटा (कोई बच्चा सिर्फ़ अपने बच्चों की जानकारी पढ़ता है, अपने माता-पिता की नहीं).
इन पाबंदियों की मदद से, हम बाद के लेआउट के लिए फ़्रैगमेंट का फिर से इस्तेमाल कर पाते हैं. इन पाबंदियों के बिना, हमें अक्सर पूरे ट्री को फिर से जनरेट करना पड़ता है. यह प्रोसेस महंगी होती है.
ज़्यादातर लेआउट, आम तौर पर इंक्रीमेंटल अपडेट होते हैं. उदाहरण के लिए, कोई वेब ऐप्लिकेशन, उपयोगकर्ता के किसी एलिमेंट पर क्लिक करने पर यूज़र इंटरफ़ेस (यूआई) के छोटे हिस्से को अपडेट करता है. आम तौर पर, लेआउट सिर्फ़ उसी हिस्से में बदलाव करना चाहिए जो स्क्रीन पर बदला है. ऐसा करने के लिए, हम पिछले ट्री के ज़्यादा से ज़्यादा हिस्सों का फिर से इस्तेमाल करते हैं. इसका मतलब है कि आम तौर पर, हमें सिर्फ़ ट्री स्ट्रक्चर को फिर से बनाना होगा.
आने वाले समय में, इस डिज़ाइन की मदद से कई दिलचस्प काम किए जा सकते हैं. जैसे, ज़रूरत पड़ने पर, थ्रेड की सीमाओं के बीच में, बिना बदलाव किए जाने वाले फ़्रैगमेंट ट्री को पास करना (किसी दूसरे थ्रेड पर अगले चरण को पूरा करने के लिए), बेहतर लेआउट ऐनिमेशन के लिए कई ट्री जनरेट करना या एक साथ कई अनुमानित लेआउट बनाना. इससे हमें मल्टी-थ्रेडिंग लेआउट की सुविधा भी मिलती है.
इनलाइन फ़्रैगमेंट आइटम
इनलाइन कॉन्टेंट (मुख्य रूप से स्टाइल किया गया टेक्स्ट) थोड़े अलग तरीके से दिखाया जाता है. बॉक्स और पॉइंटर वाली ट्री स्ट्रक्चर के बजाय, हम इनलाइन कॉन्टेंट को ट्री की जानकारी वाली फ़्लैट सूची में दिखाते हैं. इसका मुख्य फ़ायदा यह है कि इनलाइन के लिए फ़्लैट सूची का रेप्रज़ेंटेशन तेज़ होता है. साथ ही, यह इनलाइन डेटा-स्ट्रक्चर की जांच करने या उनसे क्वेरी करने के लिए भी मददगार होता है. साथ ही, यह मेमोरी के लिहाज़ से भी बेहतर होता है. यह वेब रेंडरिंग की परफ़ॉर्मेंस के लिए बहुत ज़रूरी है, क्योंकि टेक्स्ट को रेंडर करना बहुत मुश्किल होता है. साथ ही, अगर इसे ज़्यादा ऑप्टिमाइज़ नहीं किया जाता है, तो यह आसानी से पाइपलाइन का सबसे धीमा हिस्सा बन सकता है.
फ़्लैट सूची, हर इनलाइन फ़ॉर्मैटिंग कॉन्टेक्स्ट के लिए बनाई जाती है. यह सूची, इनलाइन लेआउट के सबट्री की डीप-फ़र्स्ट सर्च के क्रम में बनाई जाती है. सूची में मौजूद हर एंट्री, (ऑब्जेक्ट, वंशजों की संख्या) का टुपल होती है. उदाहरण के लिए, इस डीओएम पर विचार करें:
<div style="width: 0;">
<span style="color: blue; position: relative;">Hi</span> <b>there</b>.
</div>
width
प्रॉपर्टी को 0 पर सेट किया गया है, ताकि लाइन "नमस्ते" और "वहां" के बीच रैप हो जाए.
इस स्थिति के लिए इनलाइन फ़ॉर्मैटिंग कॉन्टेक्स्ट को ट्री के तौर पर दिखाए जाने पर, यह ऐसा दिखता है:
{
"Line box": {
"Box <span>": {
"Text": "Hi"
}
},
"Line box": {
"Box <b>": {
"Text": "There"
}
},
{
"Text": "."
}
}
फ़्लैट सूची इस तरह दिखती है:
- (लाइन बॉक्स, 2)
- (Box <span>, 1)
- (टेक्स्ट "नमस्ते", 0)
- (लाइन बॉक्स, 3)
- (बॉक्स <b>, 1)
- (टेक्स्ट "वहां", 0)
- (टेक्स्ट ".", 0)
इस डेटा स्ट्रक्चर का इस्तेमाल कई लोग करते हैं: ऐक्सेसibililty API,
और ज्यामिति एपीआई, जैसे कि
getClientRects
और contenteditable
.
हर चैनल के लिए ज़रूरी शर्तें अलग-अलग होती हैं.
ये कॉम्पोनेंट, सुविधाजनक कर्सर की मदद से फ़्लैट डेटा स्ट्रक्चर को ऐक्सेस करते हैं.
क cursor में MoveToNext
, MoveToNextLine
, CursorForChildren
जैसे एपीआई होते हैं.
टेक्स्ट कॉन्टेंट के लिए, कर्सर का यह तरीका कई वजहों से काफ़ी असरदार है:
- डीप-फ़र्स्ट सर्च ऑर्डर में, बहुत तेज़ी से दोहराव किया जा सकता है. इसका इस्तेमाल अक्सर किया जाता है, क्योंकि यह कैरेट (कैरेट) को मूव करने जैसा ही होता है. यह एक फ़्लैट सूची है, इसलिए डेप्थ-फ़र्स्ट सर्च (गहराई से शुरू की गई खोज) से सिर्फ़ अरे ऑफ़सेट को बढ़ाया जाता है, जिससे तेज़ इटरेशन और मेमोरी लोकलिटी की सुविधा मिलती है.
- यह ब्रॉड-फ़र्स्ट सर्च की सुविधा देता है. उदाहरण के लिए, लाइन और इनलाइन बॉक्स का बैकग्राउंड पेंट करते समय यह सुविधा ज़रूरी होती है.
- वंशजों की संख्या जानने से, अगले सिबलिंग पर तेज़ी से जाने में मदद मिलती है. इसके लिए, सिर्फ़ ऐरे ऑफ़सेट को उस संख्या से बढ़ाएं.
प्रॉपर्टी ट्री
डीओएम, एलिमेंट का एक ट्री (साथ में टेक्स्ट नोड) होता है. साथ ही, सीएसएस, एलिमेंट पर कई स्टाइल लागू कर सकती है.
यह चार तरीकों से दिखता है:
- लेआउट: लेआउट की पाबंदी वाले एल्गोरिदम के इनपुट.
- पेंट: एलिमेंट को कैसे पेंट और रास्टर करें (लेकिन इसके डिसेंडेंट नहीं).
- विज़ुअल: रेस्टर/ड्रॉ इफ़ेक्ट, जो डीओएम सबट्री पर लागू किए जाते हैं. जैसे, ट्रांसफ़ॉर्म, फ़िल्टर, और क्लिपिंग.
- स्क्रोल करना: अक्ष के साथ अलाइन किए गए और राउंड किए गए कोने वाले सबट्री को क्लिप करना और स्क्रोल करना.
प्रॉपर्टी ट्री, डेटा स्ट्रक्चर होते हैं. इनसे यह पता चलता है कि डीओएम एलिमेंट पर विज़ुअल और स्क्रोलिंग इफ़ेक्ट कैसे लागू होते हैं. इनसे ऐसे सवालों के जवाब देने में मदद मिलती है: स्क्रीन के हिसाब से, दिया गया डीओएम एलिमेंट कहां है और उसके लेआउट का साइज़ और पोज़िशन क्या है? और: विज़ुअल और स्क्रोलिंग इफ़ेक्ट लागू करने के लिए, जीपीयू के ऑपरेशन के किस क्रम का इस्तेमाल किया जाना चाहिए?
वेब पर विज़ुअल और स्क्रोलिंग इफ़ेक्ट का इस्तेमाल करना काफ़ी मुश्किल है. इसलिए, प्रॉपर्टी ट्री की सबसे अहम भूमिका, इस जटिलता को एक डेटा स्ट्रक्चर में बदलना है. यह स्ट्रक्चर, प्रॉपर्टी के स्ट्रक्चर और मतलब को सटीक तरीके से दिखाता है. साथ ही, डीओएम और सीएसएस की बाकी जटिलताओं को हटा देता है. इससे हमें कंपोज़िटिंग और स्क्रोलिंग के एल्गोरिदम को ज़्यादा भरोसे के साथ लागू करने में मदद मिलती है. खास तौर पर:
- गड़बड़ी की आशंका वाली ज्यामिति और अन्य गणनाओं को एक ही जगह पर केंद्रित किया जा सकता है.
- प्रॉपर्टी ट्री बनाने और अपडेट करने की जटिलता को रेंडरिंग पाइपलाइन के एक चरण में अलग कर दिया गया है.
- फ़ुल डीओएम स्टेट की तुलना में, प्रॉपर्टी ट्री को अलग-अलग थ्रेड और प्रोसेस पर भेजना ज़्यादा आसान और तेज़ है. इससे, इस्तेमाल के कई उदाहरणों के लिए इनका इस्तेमाल किया जा सकता है.
- इस्तेमाल के जितने ज़्यादा उदाहरण होंगे, उतना ही ज़्यादा फ़ायदा हमें ऊपर बनाई गई ज्यामिति कैश मेमोरी से मिलेगा. ऐसा इसलिए, क्योंकि वे एक-दूसरे के कैश मेमोरी का फिर से इस्तेमाल कर सकते हैं.
ReportingNG, कई कामों के लिए प्रॉपर्टी ट्री का इस्तेमाल करता है. इनमें ये शामिल हैं:
- पेंट और मुख्य थ्रेड से कॉम्पोज़िटिंग को अलग करना.
- एक बेहतर कंपोज़िटिंग / ड्रॉ रणनीति तय करना.
- IntersectionObserver ज्यामिति को मापना.
- ऑफ़स्क्रीन एलिमेंट और जीपीयू टेक्सचर टाइल के लिए काम न करना.
- पेंट और रेस्टर को असरदार और सटीक तरीके से अमान्य करना.
- वेबसाइट की परफ़ॉर्मेंस की अहम जानकारी देने वाली मेट्रिक में, लेआउट शिफ़्ट और सबसे बड़े एलिमेंट को रेंडर करने में लगने वाला समय मेज़र करना.
हर वेब दस्तावेज़ में चार अलग-अलग प्रॉपर्टी ट्री होते हैं: ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, और स्क्रोल.(*) ट्रांसफ़ॉर्म ट्री, सीएसएस ट्रांसफ़ॉर्म और स्क्रोलिंग को दिखाता है. (स्क्रोल ट्रांसफ़ॉर्म को 2D ट्रांसफ़ॉर्म मैट्रिक्स के तौर पर दिखाया जाता है.) क्लिप ट्री में ओवरफ़्लो क्लिप दिखती हैं. इफ़ेक्ट ट्री में, अन्य सभी विज़ुअल इफ़ेक्ट दिखते हैं: ओपैसिटी, फ़िल्टर, मास्क, ब्लेंड मोड, और क्लिप-पाथ जैसी अन्य तरह की क्लिप. स्क्रोल ट्री से स्क्रोल करने के बारे में जानकारी मिलती है. जैसे, स्क्रोल एक-दूसरे से कैसे जुड़े होते हैं. यह जानकारी, कंपोज़िटर थ्रेड पर स्क्रोल करने के लिए ज़रूरी है. प्रॉपर्टी ट्री में मौजूद हर नोड, किसी DOM एलिमेंट से लागू किए गए स्क्रोल या विज़ुअल इफ़ेक्ट को दिखाता है. अगर एक से ज़्यादा असर होते हैं, तो एक ही एलिमेंट के लिए हर ट्री में एक से ज़्यादा प्रॉपर्टी ट्री नोड हो सकते हैं.
हर ट्री की टोपोलॉजी, डीओएम के स्पैर्स रिप्रज़ेंटेशन की तरह होती है. उदाहरण के लिए, अगर ओवरफ़्लो क्लिप वाले तीन डीओएम एलिमेंट हैं, तो तीन क्लिप ट्री नोड होंगे. साथ ही, क्लिप ट्री का स्ट्रक्चर, ओवरफ़्लो क्लिप के बीच मौजूद ब्लॉक के संबंध के हिसाब से होगा. पेड़ों के बीच भी लिंक हैं. ये लिंक, नोड की रिलेटिव DOM हैरारकी और इसलिए, नोड के लागू होने के क्रम को दिखाते हैं. उदाहरण के लिए, अगर किसी DOM एलिमेंट पर ट्रांसफ़ॉर्म, फ़िल्टर वाले किसी दूसरे DOM एलिमेंट के नीचे है, तो ट्रांसफ़ॉर्म, फ़िल्टर से पहले लागू होता है.
हर DOM एलिमेंट की एक प्रॉपर्टी ट्री स्टेटस होती है. यह चार-ट्यूपल (ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, स्क्रोल) होता है. इससे उस एलिमेंट पर असर डालने वाले, सबसे नज़दीकी एलिमेंट की क्लिप, ट्रांसफ़ॉर्म, और इफ़ेक्ट ट्री नोड की जानकारी मिलती है. यह काफ़ी सुविधाजनक है, क्योंकि इस जानकारी से हमें उस एलिमेंट पर लागू होने वाली क्लिप, ट्रांसफ़ॉर्मेशन, और इफ़ेक्ट की सूची और उनके क्रम के बारे में सटीक जानकारी मिलती है. इससे हमें पता चलता है कि यह स्क्रीन पर कहां है और इसे कैसे ड्रॉ किया जाए.
उदाहरण
(सोर्स)
<html>
<div style="overflow: scroll; width: 100px; height: 100px;">
<iframe style="filter: blur(3px);
transform: rotateZ(1deg);
width: 100px; height: 300px"
id="one" srcdoc="iframe one"></iframe>
</div>
<iframe style="top:200px;
transform: scale(1.1) translateX(200px)" id=two
srcdoc="iframe two"></iframe>
</html>
पिछले उदाहरण (जो शुरुआत में दिए गए उदाहरण से थोड़ा अलग है) के लिए, जनरेट किए गए प्रॉपर्टी ट्री के मुख्य एलिमेंट यहां दिए गए हैं:
में 3 पिक्सल का ब्लर लागू होता है.सूचियां और पेंट के हिस्से दिखाना
डिसप्ले आइटम में, कम लेवल के ड्रॉइंग कमांड होते हैं (यहां देखें). इन्हें Skia की मदद से रेस्टर किया जा सकता है. डिसप्ले आइटम आम तौर पर आसान होते हैं. इनमें ड्रॉइंग करने के लिए कुछ निर्देश दिए जाते हैं, जैसे कि बॉर्डर या बैकग्राउंड बनाना. डिसप्ले आइटम की सूची बनाने के लिए, पेंट ट्री वॉक, लेआउट ट्री और उससे जुड़े फ़्रैगमेंट पर सीएसएस पेंटिंग के क्रम के हिसाब से, बार-बार जाता है.
उदाहरण के लिए:
<div id="green" style="background:green; width:80px;">
Hello world
</div>
<div id="blue" style="width:100px;
height:100px; background:blue;
position:absolute;
top:0; left:0; z-index:-1;">
</div>
इस एचटीएमएल और सीएसएस से, यहां दी गई डिसप्ले सूची बनेगी, जिसमें हर सेल एक डिसप्ले आइटम है:
व्यू का बैकग्राउंड | #blue बैकग्राउंड |
#green बैकग्राउंड |
#green इनलाइन टेक्स्ट |
---|---|---|---|
drawRect , जिसका साइज़ 800x600 है और जो सफ़ेद रंग का है. |
drawRect , जिसका साइज़ 100x100 है और जो 0,0 पोज़िशन पर है और नीले रंग का है. |
drawRect , जिसका साइज़ 80x18 है और जो 8,8 पोज़िशन पर है. साथ ही, इसका रंग हरा है. |
drawTextBlob , जिसकी पोज़िशन 8,8 है और टेक्स्ट "Hello world" है. |
डिसप्ले आइटम की सूची को पीछे से आगे के क्रम में लगाया जाता है. ऊपर दिए गए उदाहरण में, हरा div DOM क्रम में नीले div से पहले है, लेकिन CSS पेंट क्रम के लिए यह ज़रूरी है कि ऋणात्मक z-index नीला div, (चरण 3) हरे div (चरण 4.1 से पहले पेंट हो. डिसप्ले आइटम, सीएसएस पेंट ऑर्डर स्पेसिफ़िकेशन के एटॉमिक चरणों से मिलते-जुलते होते हैं. एक डीओएम एलिमेंट से कई डिसप्ले आइटम बन सकते हैं. उदाहरण के लिए, #green में बैकग्राउंड के लिए एक डिसप्ले आइटम और इनलाइन टेक्स्ट के लिए एक और डिसप्ले आइटम है. सीएसएस पेंट ऑर्डर की पूरी जानकारी देने के लिए, इस तरह की जानकारी देना ज़रूरी है. जैसे, नेगेटिव मार्जिन की वजह से इंटरलेविंग:
<div id="green" style="background:green; width:80px;">
Hello world
</div>
<div id="gray" style="width:35px; height:20px;
background:gray;margin-top:-10px;"></div>
इससे नीचे दी गई डिसप्ले सूची बनती है, जिसमें हर सेल एक डिसप्ले आइटम होता है:
व्यू का बैकग्राउंड | #green बैकग्राउंड |
#gray बैकग्राउंड |
#green इनलाइन टेक्स्ट |
---|---|---|---|
drawRect , जिसका साइज़ 800x600 है और जो सफ़ेद रंग का है. |
drawRect , जिसका साइज़ 80x18 है, जिसकी पोज़िशन 8,8 है और रंग हरा है. |
drawRect , जिसका साइज़ 35x20 है, जिसकी पोज़िशन 8,16 है और जिसका रंग स्लेटी है. |
drawTextBlob की पोज़िशन 8,8 है और टेक्स्ट "नमस्ते वर्ल्ड" टेक्स्ट है. |
डिसप्ले आइटम सूची को सेव किया जाता है और बाद के अपडेट के ज़रिए फिर से इस्तेमाल किया जाता है. अगर पेंट ट्री वॉक के दौरान कोई लेआउट ऑब्जेक्ट नहीं बदला है, तो उसके डिसप्ले आइटम को पिछली सूची से कॉपी कर लिया जाता है. एक और ऑप्टिमाइज़ेशन, सीएसएस पेंट ऑर्डर स्पेसिफ़िकेशन की प्रॉपर्टी पर निर्भर करता है: स्टैकिंग कॉन्टेक्स्ट, एटॉमिक तौर पर पेंट करते हैं. अगर स्टैकिंग कॉन्टेक्स्ट में कोई लेआउट ऑब्जेक्ट नहीं बदला है, तो पेंट ट्री वॉक, स्टैकिंग कॉन्टेक्स्ट को स्किप कर देता है और पिछली सूची से डिसप्ले आइटम के पूरे क्रम को कॉपी कर लेता है.
पेंट ट्री वॉक के दौरान, प्रॉपर्टी ट्री की मौजूदा स्थिति को बनाए रखा जाता है और डिसप्ले आइटम की सूची को डिसप्ले आइटम के "चंक" में बांटा जाता है. ये चंक, प्रॉपर्टी ट्री की एक ही स्थिति के साथ शेयर होते हैं. इसका उदाहरण यहां दिया गया है:
<div id="scroll" style="background:pink; width:100px;
height:100px; overflow:scroll;
position:absolute; top:0; left:0;">
Hello world
<div id="orange" style="width:75px; height:200px;
background:orange; transform:rotateZ(25deg);">
I'm falling
</div>
</div>
इससे, यहां दी गई डिसप्ले सूची बनती है, जहां हर सेल एक डिसप्ले आइटम है:
व्यू का बैकग्राउंड | #scroll बैकग्राउंड |
#scroll इनलाइन टेक्स्ट |
#orange बैकग्राउंड |
#orange इनलाइन टेक्स्ट |
---|---|---|---|---|
drawRect , जिसका साइज़ 800x600 है और जो सफ़ेद रंग का है. |
drawRect का साइज़ 100x100, पोज़िशन 0,0, और रंग गुलाबी है. |
drawTextBlob की पोज़िशन 0,0 और टेक्स्ट "नमस्ते दुनिया" है. |
drawRect , जिसका साइज़ 75x200 है, जिसकी पोज़िशन 0,0 है और रंग नारंगी है. |
drawTextBlob , जिसकी पोज़िशन 0,0 है और टेक्स्ट "मैं गिर रहा/रही हूं" है. |
इसके बाद, ट्रांसफ़ॉर्म प्रॉपर्टी ट्री और पेंट चंक इस तरह होंगे (कम शब्दों में बताया गया है):
पेंट चंक की क्रम से लगाई गई सूची, रेंडरिंग पाइपलाइन के लेयराइज़ेशन चरण के इनपुट होते हैं. ये चंक, डिसप्ले आइटम और प्रॉपर्टी ट्री की स्थिति के ग्रुप होते हैं. पेंट चंक की पूरी सूची को एक कॉम्पोज़िट लेयर में मर्ज किया जा सकता है और एक साथ रेस्टर किया जा सकता है. हालांकि, हर बार जब उपयोगकर्ता स्क्रोल करता है, तो इसके लिए ज़्यादा रेस्टर करने की ज़रूरत होगी. हर पेंट चंक के लिए एक कंपोजिट लेयर बनाई जा सकती है और फिर उसे अलग-अलग रेस्टर किया जा सकता है, ताकि फिर से रेस्टर करने की ज़रूरत न पड़े. हालांकि, इससे जीपीयू मेमोरी जल्दी खत्म हो जाएगी. लेयर बनाने के चरण में, जीपीयू मेमोरी और लागत कम करने के बीच समझौता करना पड़ता है. एक अच्छा सामान्य तरीका यह है कि डिफ़ॉल्ट रूप से कई हिस्सों को मर्ज किया जाए, न कि उन पेंट हिस्सों को मर्ज किया जाए जिनमें प्रॉपर्टी ट्री की स्थितियां हैं और जिनके कंपोज़िटर थ्रेड पर बदलने की संभावना होती है, जैसे कि कंपोज़िटर-थ्रेड स्क्रोलिंग या कंपोज़िटर-थ्रेड ट्रांसफ़ॉर्म ऐनिमेशन के साथ.
ऊपर दिए गए उदाहरण में, दो कॉम्पोज़िट लेयर बननी चाहिए:
- 800x600 वाली एक कंपोज़िट लेयर, जिसमें ड्रॉइंग के कमांड शामिल हैं:
drawRect
का साइज़ 800x600 और रंग सफ़ेद होdrawRect
, जिसकी पोज़िशन 0,0 है और जिसका साइज़ 100x100 है और जो गुलाबी रंग में है
- एक 144x224 कंपोज़िट लेयर, जिसमें ड्रॉइंग के निर्देश होते हैं:
drawTextBlob
की पोज़िशन 0,0 है और टेक्स्ट "हैलो वर्ल्ड" है- 0,18 का अनुवाद
rotateZ(25deg)
drawRect
का साइज़ 75x200, पोज़िशन 0,0, और रंग नारंगीdrawTextBlob
, जिसकी पोज़िशन 0,0 है और टेक्स्ट "I'm falling" है
अगर उपयोगकर्ता #scroll
को स्क्रोल करता है, तो दूसरी कंपोजिट लेयर को दूसरी जगह ले जाया जाता है. हालांकि, इसके लिए रेस्टराइज़ेशन की ज़रूरत नहीं होती.
उदाहरण के लिए, प्रॉपर्टी ट्री के पिछले सेक्शन में, छह पेंट चंक हैं. प्रॉपर्टी ट्री की स्थितियों (ट्रांसफ़ॉर्म, क्लिप, इफ़ेक्ट, स्क्रोल) के साथ-साथ, ये भी हैं:
- दस्तावेज़ का बैकग्राउंड: दस्तावेज़ स्क्रोल, दस्तावेज़ क्लिप, रूट, दस्तावेज़ स्क्रोल.
- डिव के लिए हॉरिज़ॉन्टल, वर्टिकल, और स्क्रोल कॉर्नर (तीन अलग-अलग पेंट चंक):
दस्तावेज़ स्क्रोल, दस्तावेज़ क्लिप,
#one
ब्लर, दस्तावेज़ स्क्रोल. - iframe
#one
:#one
घुमाएं, ओवरफ़्लो स्क्रोल क्लिप,#one
धुंधला करें, div स्क्रोल. - Iframe
#two
:#two
स्केल, दस्तावेज़ क्लिप, रूट, दस्तावेज़ स्क्रोल.
कंपोजिटर फ़्रेम: सर्फ़ेस, रेंडर सर्फ़ेस, और जीपीयू टेक्चर टाइल
ब्राउज़र और रेंडर प्रोसेस, कॉन्टेंट को रेस्टर में बदलने की प्रोसेस को मैनेज करती हैं. इसके बाद, स्क्रीन पर दिखाने के लिए, विज़ प्रोसेस में कंपोजिटर फ़्रेम सबमिट करती हैं. कंपोज़िटर फ़्रेम यह दिखाते हैं कि रास्टराइज़ किए गए कॉन्टेंट को एक साथ कैसे स्टिच करें और जीपीयू का इस्तेमाल करके, बेहतर तरीके से कैसे ड्रॉ करें.
टाइल
सिद्धांत रूप से, रेंडर प्रोसेस या ब्राउज़र प्रोसेस कंपोजिटर, पिक्सल को रेंडरर व्यूपोर्ट के पूरे साइज़ के एक टेक्सचर में रेस्टर कर सकता है और उस टेक्सचर को विज़ में सबमिट कर सकता है. इसे दिखाने के लिए, डिसप्ले कंपोजिटर को उस एक टेक्सचर से पिक्सल को कॉपी करके, फ़्रेम बफ़र (उदाहरण के लिए, स्क्रीन) में सही जगह पर चिपकाना होगा. हालांकि, अगर उस कंपोजिटर को एक पिक्सल भी अपडेट करना है, तो उसे पूरे व्यूपोर्ट को फिर से रेस्टर करना होगा और Viz में एक नया टेक्सचर सबमिट करना होगा.
इसके बजाय, व्यूपोर्ट को टाइल में बांट दिया गया है. अलग जीपीयू टेक्सचर टाइल, हर टाइल को व्यूपोर्ट के हिस्से के लिए रास्टराइज़ किए गए पिक्सल के साथ बैक करती है. इसके बाद रेंडरर अलग-अलग टाइल को अपडेट कर सकता है या मौजूदा टाइल की जगह भी बदल सकता है. उदाहरण के लिए, किसी वेबसाइट को स्क्रोल करते समय, मौजूदा टाइल की पोज़िशन ऊपर की ओर शिफ़्ट हो जाएगी. साथ ही, पेज पर नीचे मौजूद कॉन्टेंट के लिए, सिर्फ़ कभी-कभी नई टाइल को रेस्टर करने की ज़रूरत होगी.
क्वाड और प्लैटफ़ॉर्म
जीपीयू टेक्स्चर टाइल, एक खास तरह की क्वाड होती हैं. यह टेक्स्चर की किसी कैटगरी का एक फैंसी नाम है. क्वॉड, इनपुट टेक्सचर की पहचान करता है. साथ ही, उस पर विज़ुअल इफ़ेक्ट लागू करने और उसे बदलने का तरीका बताता है. उदाहरण के लिए, सामान्य कॉन्टेंट वाली टाइल में ट्रांसफ़ॉर्म होता है. इससे टाइल ग्रिड में उनके x और y की पोज़िशन को पता चलता है.
रेस्टर की गई इन टाइल को रेंडर पास में लपेटा जाता है. यह क्वाड की सूची होती है. रेंडर पास में पिक्सल की कोई जानकारी नहीं होती. इसके बजाय, इसमें यह जानकारी होती है कि पिक्सल का मनचाहा आउटपुट पाने के लिए, हर क्वॉड को कहां और कैसे ड्रॉ करना है. हर जीपीयू टेक्सचर टाइल के लिए एक ड्रॉ क्वॉड होता है. डिसप्ले कंपोजिटर को रेंडर पास के लिए, पिक्सल का मनमुताबिक आउटपुट पाने के लिए, सिर्फ़ क्वाड की सूची में बदलाव करना होता है. इसके लिए, वह हर क्वाड को तय किए गए विज़ुअल इफ़ेक्ट के साथ ड्रॉ करता है. रेंडर पास के लिए ड्रॉ क्वॉड को कॉम्पोज़ करने का काम, जीपीयू पर बेहतर तरीके से किया जा सकता है. ऐसा इसलिए, क्योंकि इस्तेमाल किए जा सकने वाले विज़ुअल इफ़ेक्ट को ध्यान से चुना जाता है, ताकि वे सीधे जीपीयू की सुविधाओं पर मैप हो सकें.
रेस्टर की गई टाइल के अलावा, ड्रॉ क्वाड के अन्य टाइप भी होते हैं. उदाहरण के लिए, सॉलिड कलर ड्रॉ क्वाड ऐसे होते हैं जिनमें कोई टेक्स्चर नहीं होता. इसके अलावा, वीडियो या कैनवस जैसे टाइल टेक्स्चर के लिए टेक्स्चर ड्रॉ क्वाड होते हैं.
कॉम्पोज़िटर फ़्रेम में, किसी दूसरे कॉम्पोज़िटर फ़्रेम को भी एम्बेड किया जा सकता है. उदाहरण के लिए, ब्राउज़र कंपोजिटर, ब्राउज़र यूज़र इंटरफ़ेस (यूआई) के साथ एक कंपोजिटर फ़्रेम बनाता है. साथ ही, एक खाली रेक्टैंगल बनाता है, जहां रेंडर कंपोजिटर कॉन्टेंट को एम्बेड किया जाएगा. इसका एक और उदाहरण है साइट आइसोलेटेड iframe. सर्फ़ेस की मदद से, इन्हें एम्बेड किया जाता है.
जब कोई कंपोजिटर कोई कंपोजिटर फ़्रेम सबमिट करता है, तो उसके साथ एक आइडेंटिफ़ायर होता है. इसे सर्फ़ेस आईडी कहा जाता है. इससे दूसरे कंपोजिटर फ़्रेम, रेफ़रंस के ज़रिए इसे एम्बेड कर सकते हैं. किसी खास सर्वफ़ेस आईडी के साथ सबमिट किया गया नया कंपोजिटर फ़्रेम, Viz सेव करता है. इसके बाद, कोई दूसरा कंपोजिटर फ़्रेम, सर्वफ़ेस ड्रॉ क्वॉड के ज़रिए इसका रेफ़रंस दे सकता है. इसलिए, Viz को पता होता है कि क्या ड्रॉ करना है. ध्यान दें कि सरफ़ेस ड्रॉ क्वॉड में सिर्फ़ सरफ़ेस आईडी होते हैं, न कि टेक्सचर.
इंटरमीडिएट रेंडर पास
कुछ विज़ुअल इफ़ेक्ट, जैसे कि कई फ़िल्टर या बेहतर ब्लेंड मोड के लिए, ज़रूरी है कि इंटरमीडिएट टेक्स्चर में दो या उससे ज़्यादा क्वाड ड्रॉ किए जाएं. इसके बाद, जीपीयू पर डेस्टिनेशन बफ़र को इंटरमीडिएट टेक्सचर के तौर पर दिखाया जाता है या किसी अन्य इंटरमीडिएट टेक्सचर का इस्तेमाल किया जाता है. ऐसा करने पर, विज़ुअल इफ़ेक्ट को एक ही समय पर लागू किया जाता है. ऐसा करने के लिए, कंपोजिटर फ़्रेम में रेंडर पास की सूची होती है. हमेशा एक रूट रेंडर पास होता है, जो आखिर में ड्रॉ किया जाता है और जिसका डेस्टिनेशन फ़्रेम बफ़र से जुड़ा होता है. इसके अलावा, और भी पास हो सकते हैं.
एक से ज़्यादा रेंडर पास की संभावना होने की वजह से, इसे "रेंडर पास" कहा जाता है. हर पास को जीपीयू पर क्रम से, कई "पास" में चलाया जाना चाहिए, जबकि एक पास को एक बड़े पैमाने पर पैरलल जीपीयू कंप्यूटेशन में पूरा किया जा सकता है.
एग्रीगेशन
विज़ में कई कंपोजिटर फ़्रेम सबमिट किए जाते हैं और उन्हें स्क्रीन पर एक साथ दिखाया जाता है. ऐसा एग्रीगेशन के चरण से किया जाता है, जो उन्हें सिंगल, एग्रीगेटेड कंपोज़िटर फ़्रेम में बदल देता है. एग्रीगेशन, सर्फ़ेस ड्रॉ क्वाड को उन कॉम्पोज़िटर फ़्रेम से बदल देता है जिन्हें वे तय करते हैं. यह बीच में दिखने वाले ग़ैर-ज़रूरी टेक्स्चर या ऑफ़स्क्रीन कॉन्टेंट को ऑप्टिमाइज़ करने का भी मौका है. उदाहरण के लिए, कई मामलों में साइट से अलग किए गए iframe के लिए, कॉम्पोज़र फ़्रेम को अपने इंटरमीडिएट टेक्सचर की ज़रूरत नहीं होती. साथ ही, इसे सही ड्रॉ क्वाड की मदद से सीधे फ़्रेम बफ़र में ड्रॉ किया जा सकता है. एग्रीगेशन फ़ेज़ में, ऐसे ऑप्टिमाइज़ेशन का पता लगाया जाता है और उन्हें लागू किया जाता है. ऐसा, दुनिया भर के डेटा के आधार पर किया जाता है. इस डेटा को अलग-अलग रेंडर कंपोजर ऐक्सेस नहीं कर सकते.
उदाहरण
यहां कॉम्पोज़िटर फ़्रेम दिए गए हैं, जो इस पोस्ट की शुरुआत में दिए गए उदाहरण को दिखाते हैं.
foo.com/index.html
प्लैटफ़ॉर्म: id=0- रेंडर पास 0: आउटपुट में ड्रॉ करें.
- रेंडर पास ड्रॉ क्वाड: तीन पिक्सल ब्लर के साथ ड्रॉ करें और रेंडर पास 0 में क्लिप करें.
- पहला रेंडर पास:
#one
iframe के टाइल कॉन्टेंट के लिए क्वाड बनाएं. साथ ही, हर क्वाड के लिए x और y पोज़िशन दें.
- पहला रेंडर पास:
- सरफ़ेस ड्रॉ क्वॉड: आईडी 2 के साथ, स्केल और ट्रांसलेट ट्रांसफ़ॉर्म के साथ ड्रॉ किया गया.
- रेंडर पास ड्रॉ क्वाड: तीन पिक्सल ब्लर के साथ ड्रॉ करें और रेंडर पास 0 में क्लिप करें.
- रेंडर पास 0: आउटपुट में ड्रॉ करें.
- ब्राउज़र यूज़र इंटरफ़ेस (यूआई) का प्लैटफ़ॉर्म: आईडी=1
- रेंडर पास 0: आउटपुट में ड्रॉ करें.
- ब्राउज़र यूज़र इंटरफ़ेस (यूआई) के लिए क्वाड ड्रॉ करना (टाइल भी)
- रेंडर पास 0: आउटपुट में ड्रॉ करें.
bar.com/index.html
surface: ID=2- रेंडर पास 0: आउटपुट में ड्रॉ करें.
#two
iframe के कॉन्टेंट के लिए क्वाड बनाएं. साथ ही, हर क्वाड के लिए x और y पोज़िशन दें.
- रेंडर पास 0: आउटपुट में ड्रॉ करें.
इलस्ट्रेशन: यूना क्रेवेट.