Lulucat

ଚକ୍ ଟୁଲ୍‌ର କାର୍ଯ୍ୟଦକ୍ଷତା: ପୂରା ସ୍କ୍ରିନ୍ ପାସ୍‌ରୁ scissor rectangle ପର୍ଯ୍ୟନ୍ତ

Gaoge ZhangGaoge Zhang

Lulucat Notes ର ଚକ୍ ଟୁଲ୍ ଘନ ହସ୍ତଲିପି ଅଞ୍ଚଳରେ ଧୀର ହୋଇଯାଉଥିଲା। ମୁଖ୍ୟ ବାଧା 3,571ଟି input sample ନୁହେଁ — ପ୍ରତି frame ରେ ଚାଲୁଥିବା 70ଟି ପୂରା-ସ୍କ୍ରିନ୍ scratch pass ଥିଲା। ବାତିଲ ହୋଇଥିବା କମ୍-ରେଜଲୁସନ୍ cache ଏବଂ ପ୍ରତ୍ୟେକ stroke ପାଇଁ scissor rectangle ଏହି କାହାଣୀର ଅବଶିଷ୍ଟ ଅଂଶ କହେ।

255% zoom ରେ iPad ଉପରେ Lulucat Notes ର କ୍ରପ୍ କରାଯାଇଥିବା ଦୃଶ୍ୟ, ଯେଉଁଥିରେ ଲାଲ ଓ ନୀଳ ଚକ୍‌ରେ ଚୀନ୍‌ର ଏକ ପାରମ୍ପରିକ ଲେଖାର ଅଂଶ ଦେଖାଯାଉଛି ଏବଂ app toolbar ର କିଛି ଅଂଶ ମଧ୍ୟ ଦିଶୁଛି।

255% zoom ରେ ଶେଷ device build ଉପରେ ଲାଲ ଓ ନୀଳ ଚକ୍, 155 strokes।

Lulucat Notes ର ଚକ୍ ଟୁଲ୍‌ରେ ଏକ ନିର୍ଦ୍ଦିଷ୍ଟ କାର୍ଯ୍ୟଦକ୍ଷତା ସମସ୍ୟା ଥିଲା: ଖାଲି ଅଞ୍ଚଳରେ ଲେଖିବା ସ୍ୱଚ୍ଛନ୍ଦ ଲାଗୁଥିଲା, କିନ୍ତୁ ପୂର୍ବରୁ ଚକ୍ ଷ୍ଟ୍ରୋକ୍‌ରେ ଭରିଥିବା ଅଞ୍ଚଳକୁ ଯିବାବେଳେ ପେନ୍‌ର ଟିପ୍ ପଛକୁ ପଡ଼ୁଥିଲା। ସେହି ଅଞ୍ଚଳରେ ଲେଖିବା ଜାରି ରଖିଲେ canvas ଚଳାଇବା ମଧ୍ୟ ଧୀରେ ଧୀରେ ଧୀର ହେଉଥିଲା।

ସାଧାରଣ ହସ୍ତଲିପିର ଗୋଟିଏ ପୃଷ୍ଠା ହିଁ ସମସ୍ୟାଟି ଦେଖାଇବାକୁ ପର୍ଯ୍ୟାପ୍ତ ଥିଲା: 300% zoom, ସ୍ଥାନୀୟ ଅଞ୍ଚଳରେ 70ଟି ଦୃଶ୍ୟମାନ ଚକ୍ ଷ୍ଟ୍ରୋକ୍, ମୋଟ 3,571ଟି input sample point। ଖାଲି ଅଞ୍ଚଳ ସ୍ୱଚ୍ଛନ୍ଦ ରହିଲା; କେବଳ ଷ୍ଟ୍ରୋକ୍‌ଗୁଡ଼ିକ ଘନ ହୋଇଥିବା ଅଞ୍ଚଳ ଧୀର ହେଲା।

ସୁଧାର ପରେ ସେହି ପୃଷ୍ଠାରେ 255% zoom ରେ ନୂଆ ଲେଖା ଜାରି ରଖିହେବ, ଏବଂ ପେନ୍ ଲାଗିଥିବା ସମୟରେ ଓ canvas ଚଳାଇବାବେଳେ — ଦୁଇ ସମୟରେ — ପୂର୍ବରୁ ଥିବା ଷ୍ଟ୍ରୋକ୍‌ଗୁଡ଼ିକର ସମ୍ପୂର୍ଣ୍ଣ ସ୍ପଷ୍ଟତା ରହେ।

255% zoom ରେ iPad ଉପରେ Lulucat Notes, ଲାଲ ଓ ନୀଳ ଚକ୍ ହସ୍ତଲିପି ଦେଖାଉଛି। ଲେଖାଟି “天行健,君子以自强不息;地势坤,君子以厚德载物” — ଏକ ପାରମ୍ପରିକ ଚୀନ୍ passage। ଉପର ଡାହାଣ ପଟେ ଏକ ନୀଳ Lulucat mascot ଅଛି। ତଳ toolbar ରେ 155 stroke count, Save, Clear ଏବଂ 255% zoom slider ଦେଖାଯାଉଛି।

ଶେଷ device screenshot, ମୋଟ 155 strokes। ଏହି zoom level ରେ ପେନ୍ ଲାଗିବା କିମ୍ବା canvas ଚଳାଇବା ସମୟରେ ପୂର୍ବରୁ ଥିବା ଷ୍ଟ୍ରୋକ୍‌ଗୁଡ଼ିକର ସ୍ପଷ୍ଟତା ସାମୟିକ ଭାବେ ବଦଳେ ନାହିଁ।

ଚକ୍ ପାଇଁ scratch texture କାହିଁକି ଦରକାର

ଏକ ସାଧାରଣ ପେନ୍ ପ୍ରତ୍ୟେକ ବୃତ୍ତାକାର stamp କୁ source-over blending ଦ୍ୱାରା ink texture ଉପରେ ସିଧାସଳଖ composite କରିପାରେ। ଚକ୍ ଏଥିରେ grain ନିୟନ୍ତ୍ରଣର ଏକ ଅତିରିକ୍ତ ସ୍ତର ଯୋଡ଼େ: renderer ପ୍ରଥମେ ସମ୍ପୂର୍ଣ୍ଣ stroke ର body coverage ଓ depth ସଞ୍ଚୟ କରେ, ପରେ କେଉଁ ସ୍ଥାନରେ ଚକ୍ ଧୂଳି ପଡ଼ିବ ତାହା ନିର୍ଣ୍ଣୟ କରିବାକୁ ଏକ fixed grain texture ବ୍ୟବହାର କରେ, ଏବଂ ଶେଷରେ ଫଳାଫଳକୁ ପୂର୍ବରୁ ଥିବା ink ଉପରେ composite କରେ।

ଏହି scratch texture ଗୋଟିଏ ଚକ୍ stroke କୁ ଅଲଗା ରଖେ। ଏହି isolation ଗୁରୁତ୍ୱପୂର୍ଣ୍ଣ, କାରଣ ଏକେ stroke ଭିତରର stamps ଗୁଡ଼ିକ ଭାରି overlap କରନ୍ତି; ପ୍ରତ୍ୟେକ stamp କୁ ଯଦି ଅଲଗା ଭାବରେ grain gate କରାଯାଏ, stroke ର ମଧ୍ୟ ରେଖାରେ ରଙ୍ଗ ପୁଣିପୁଣି ସଞ୍ଚିତ ହେବ ଏବଂ sampling density ବଦଳିଲେ ଚକ୍‌ର ଛିଦ୍ରଗୁଡ଼ିକ ମଧ୍ୟ ବଦଳିଯିବ।

ଉଚ୍ଚ zoom ରେ Lulucat Notes ବର୍ତ୍ତମାନ viewport ରେ ଦୃଶ୍ୟମାନ vector stroke ଗୁଡ଼ିକୁ ପୁନଃଆଙ୍କନ କରେ। ପୁରୁଣା implementation ପ୍ରତ୍ୟେକ ଦୃଶ୍ୟମାନ ଚକ୍ stroke ପାଇଁ ଏହି ପଦକ୍ଷେପ ନେଉଥିଲା:

  1. ମୁଖ୍ୟ render encoder ଶେଷ କରିବା;
  2. scratch texture କୁ clear କରିବା;
  3. ଏହି ଗୋଟିଏ ଚକ୍ stroke କୁ scratch ଭିତରେ ଆଙ୍କିବା;
  4. ମୁଖ୍ୟ render encoder କୁ ପୁଣି ଖୋଲିବା;
  5. ପୂରା ସ୍କ୍ରିନ୍ triangle ଦ୍ୱାରା scratch କୁ drawable ଉପରେ ପୁଣି composite କରିବା।

ଗୋଟିଏ stroke ର ଅର୍ଥବୋଧ ଠିକ୍ ଥିଲା, କିନ୍ତୁ କାମର ପରିସର ଅତ୍ୟଧିକ ବଡ଼ ଥିଲା। iPad ର drawable ଆକାର 2732×2048 — ପ୍ରାୟ 5.6 million pixels। ପ୍ରତ୍ୟେକ ଚକ୍ stroke ଗୋଟିଏ scratch pass ଏବଂ ଗୋଟିଏ ପୂରା-ସ୍କ୍ରିନ୍ composite ଚାଲୁ କରୁଥିଲା। ସତୁରିଟି ଚକ୍ stroke ର ଅର୍ଥ ପ୍ରାୟ 141ଟି render encoder ଏବଂ 70ଟି ପୂରା-ସ୍କ୍ରିନ୍ composite।

ଦୃଶ୍ୟମାନ ଚକ୍ stroke ର ସଂଖ୍ୟାକୁ ଏବଂ drawable pixel count କୁ ଧରନ୍ତୁ। କେବଳ pixel coverage ସହ ବଢ଼ୁଥିବା କାମକୁ ଧରିଲେ, ପୁରୁଣା implementation ପ୍ରାୟ

ପ୍ରତ୍ୟେକ ଚକ୍ stroke ର ଏକ fixed render-pass overhead ମଧ୍ୟ ଥିଲା, ତେଣୁ ସେହି ଖର୍ଚ୍ଚ ମଧ୍ୟ ସହ linear ଭାବରେ ବଢ଼ୁଥିଲା। 3,571ଟି input point କେବଳ ଦ୍ୱିତୀୟ ସ୍ତରର ଖର୍ଚ୍ଚ ଦେଉଥିଲା। ସ୍ଥାନୀୟ stroke count ସହ ବଢ଼ୁଥିବା କାମଟି ଥିଲା ପ୍ରତ୍ୟେକ stroke ଦ୍ୱାରା ଚାଲୁ ହେଉଥିବା ପୂରା-ସ୍କ୍ରିନ୍ କାମର ପରିସର।

ମାପ 12.9-inch iPad Pro (5th generation, M1) ରେ iPadOS 18.6.2 ସହିତ ନିଆଯାଇଥିଲା। ଏହି ନିର୍ଦ୍ଦିଷ୍ଟ iPad — ଯାହାକୁ ତଳେ LucasPad କୁହାଯାଇଛି — ରେ ଏକେ viewport ପାଇଁ ପରିବର୍ତ୍ତନ ପୂର୍ବରୁ ଓ ପରେର GPU timestamp ତୁଳନା କଲୁ; ଏଥିପାଇଁ ସେହି Debug device build ର command-buffer timestamp ବ୍ୟବହାର କରାଗଲା। ତଳର range ଗୁଡ଼ିକ ବହୁ frame ର log ରେ ଦେଖାଯାଇଥିବା ସାଧାରଣ ଉତ୍ତାର-ଚଢ଼ା, ବ୍ୟବହାରକାରୀଙ୍କୁ ଦିଆଯାଉଥିବା ଭାର୍ସନ୍‌ର frame-rate ପ୍ରତିଶ୍ରୁତି ନୁହେଁ। 70ଟି ଦୃଶ୍ୟମାନ ଚକ୍ stroke ଥିଲେ ଗୋଟିଏ frame ପାଇଁ ସାଧାରଣତଃ 52–60 ms GPU time ଲାଗୁଥିଲା; ପ୍ରାୟ 120ଟି stroke ଥିବା ଅଞ୍ଚଳରେ GPU time 77–80 ms କୁ ବଢ଼ିଥିଲା।

Scratch ଓ composite pass ର ପୂରା-ସ୍କ୍ରିନ୍ rectangle ର area ଆଧାରରେ ଅନୁମାନ କଲେ, ପ୍ରତି frame ର theoretical work scope ପ୍ରାୟ 783 million pixels ଠାରୁ 1.34 billion pixels କୁ ବଢ଼ିଲା। ଏହି ସଂଖ୍ୟା rectangle area ଗୁଡ଼ିକର ଯୋଗଫଳ; ଏହା fragment invocation count, video-memory read/write byte କିମ୍ବା GPU hardware counter ସହ ସମାନ ନୁହେଁ। Metal ର fast clear, attachment load/store ଏବଂ pass switching ଏବେ ମଧ୍ୟ GPU ଓ driver ର ନିୟନ୍ତ୍ରଣରେ ରହେ।

ଏହା ମଧ୍ୟ ବୁଝାଏ ଯେ ଖାଲି ଅଞ୍ଚଳ କାହିଁକି ସ୍ୱଚ୍ଛନ୍ଦ ରହିଲା। Visibility culling viewport ବାହାରେ ଥିବା stroke କୁ skip କରେ; ଖାଲି ଅଞ୍ଚଳରେ ପ୍ରାୟ ଶୂନ୍ୟ, ଘନ ଅଞ୍ଚଳରେ ବଢ଼ିଚାଲେ।

0.85 ms ରେ ଏକ ଭୁଲ ଉତ୍ତର

App ରେ ପୂର୍ବରୁ ସମ୍ପୂର୍ଣ୍ଣ ପୃଷ୍ଠାର ink texture ଥିଲା, ପ୍ରତ୍ୟେକ point ପାଇଁ ଦୁଇଟି pixel ରେ baked। ଲେଖିବା, canvas ଚଳାଇବା ଓ zoom କରିବା ସମୟରେ ଏହି texture କୁ ସିଧାସଳଖ ଦେଖାଇବାକୁ ଚେଷ୍ଟା କଲୁ; କେବଳ ବର୍ତ୍ତମାନର Apple Pencil stroke କୁ live vector ଭାବେ ରଖିଲୁ। Interaction ଶେଷ ହେବା ପରେ ଆଉ ଗୋଟିଏ frame ରେ high-resolution vector result ପୁଣି render ହେଉଥିଲା।

ଏହି ପଦ୍ଧତିର performance ବହୁତ ଭଲ ଥିଲା। 300% zoom ର ସେହି ଘନ ଅଞ୍ଚଳରେ GPU time 0.84–0.85 ms କୁ କମିଗଲା ଏବଂ ପୂର୍ବରୁ ଥିବା ଚକ୍ stroke ର ସଂଖ୍ୟା ସହ ଆଉ ବଢ଼ିଲା ନାହିଁ।

କିନ୍ତୁ ପ୍ରକୃତ device ରେ ସମସ୍ୟାଟି ମଧ୍ୟ ସ୍ପଷ୍ଟ ଥିଲା। 300% zoom ରେ ପ୍ରତ୍ୟେକ point ପାଇଁ ପ୍ରାୟ ଛଅଟି screen pixel ଦରକାର ଥିଲା, କିନ୍ତୁ cache କେବଳ ଦୁଇଟି ଦେଉଥିଲା। Apple Pencil screen କୁ ଛୁଇଁବା ମାତ୍ରେ ସମସ୍ତ ପୂର୍ବରୁ ଥିବା stroke ଏକ ନରମ low-resolution image ହୋଇଯାଉଥିଲା; Pencil ଉଠାଇଲେ ସେଗୁଡ଼ିକ ପୁଣି ସମ୍ପୂର୍ଣ୍ଣ ସ୍ପଷ୍ଟ ହେଉଥିଲା।

Tester ଗୋଟିଏ କଥା କହିଲେ: “ମୁଁ ଲେଖୁଥିବାବେଳେ ସମ୍ପୂର୍ଣ୍ଣ canvas ଧୁସର ହୋଇଯାଏ। ଛାଡ଼ିଦେଲେ ପୁଣି ସ୍ପଷ୍ଟ ହୋଇଯାଏ।”

ଏହି optimization କୁ ହଟାଇଦିଆଗଲା। 0.85 ms ସବୁଠାରୁ କମ୍ ମାପାଯାଇଥିବା result ଥିଲା, କିନ୍ତୁ ଏହା ଗ୍ରହଣଯୋଗ୍ୟ ଚକ୍ ଟୁଲ୍ ନୁହେଁ। ପୂର୍ବରୁ ଥିବା stroke ଲେଖାର feedback ର ଅଂଶ; ପେନ୍ ଲାଗିବା ସମୟରେ ସେମାନଙ୍କର ସ୍ପଷ୍ଟତା ବଦଳିପାରିବ ନାହିଁ।

ପ୍ରତ୍ୟେକ ଚକ୍ stroke କୁ ନିଜ rectangle ମଧ୍ୟରେ ସୀମିତ କରିବା

ଶେଷ ସୁଧାର per-stroke scratch ଓ per-stroke compositing କୁ ରଖିଲା, କେବଳ pixel work scope କୁ କମାଇଲା। ପ୍ରତ୍ୟେକ stroke ର ସମସ୍ତ stamp radius ର union ରୁ ମିଳୁଥିବା ଏକ canvas bounding box ପୂର୍ବରୁ ଥିଲା। Renderer ଏହି bounding box କୁ ବର୍ତ୍ତମାନ viewport ର drawable coordinate ରେ ପରିବର୍ତ୍ତନ କରେ ଏବଂ antialiasing margin ପାଇଁ ଦୁଇଟି pixel ଯୋଡ଼େ:

ସେହି scissor rectangle କୁ ତିନୋଟି କାମରେ ବ୍ୟବହାର କରାଯାଏ: scratch କୁ clear କରିବା, stroke ଆଙ୍କିବା ଏବଂ result କୁ ମୁଖ୍ୟ surface କୁ ପୁଣି composite କରିବା।

let rect = displayScissorRect(for: stroke.bounds, viewport: viewport)

scratchEncoder.setScissorRect(rect)
clearScratchExplicitly()
drawStrokeIntoScratch(stroke)

mainEncoder.setScissorRect(rect)
compositeChalkFromScratch(stroke)
mainEncoder.setScissorRect(fullDrawable)

4096² ink texture ର baking ଓ partial replay ପାଇଁ ମଧ୍ୟ ଏହି logic ବ୍ୟବହୃତ ହୁଏ। ତେଣୁ high-zoom display ଓ ଲେଖା ସ୍ଥିର ହୋଇଥିବା ink layer ଚକ୍‌ର ଦୁଇଟି ଭିନ୍ନ behavior ତିଆରି କରେ ନାହିଁ।

ଏଠାରେ ଦୁଇଟି ସହଜରେ ଛାଡ଼ିଯାଇପାରୁଥିବା detail ଅଛି।

ପ୍ରଥମେ, render pass ର loadAction = .clear attachment load stage ରେ ହୁଏ ଏବଂ rasterization scissor ଦ୍ୱାରା ସୀମିତ ହୁଏ ନାହିଁ। ଏହାକୁ ବ୍ୟବହାର କରିଚାଲିଲେ ସମ୍ପୂର୍ଣ୍ଣ scratch texture ତଥାପି clear ହେବ। ଠିକ୍ କରାଯାଇଥିବା pass .dontCare ବ୍ୟବହାର କରେ, ତାପରେ scissor ଭିତରେ clear_fragment ଆଙ୍କେ। ଏହି rectangle ପରେ ସମ୍ପୂର୍ଣ୍ଣ ଭାବରେ ଲେଖାଯାଏ ଏବଂ composite କେବଳ ସେହି rectangle ପଢ଼େ, ତେଣୁ attachment ର ପୁରୁଣା contents load କରିବା ଦରକାର ହୁଏ ନାହିଁ।

ଦ୍ୱିତୀୟରେ, ପ୍ରତ୍ୟେକ ଚକ୍ stroke ର composite ଶେଷ ହେବା ପରେ ବାହାରର scissor କୁ ପୁଣି restore କରିବା ଦରକାର। ଏହି state-restoration line ଛାଡ଼ିଦେଲେ ପରବର୍ତ୍ତୀ pen, image କିମ୍ବା selection ପୂର୍ବରୁ ଥିବା ଚକ୍ stroke ର ସୀମା ମଧ୍ୟରେ clipped ହୋଇ ରହିବ; ଫଳରେ stroke କିମ୍ବା image ର କିଛି ଅଂଶ ନଥିବା ପରି ଦେଖାଯିବ।

ଚକ୍‌ର grain ଏବେ ମଧ୍ୟ rectangle ଭିତରର local UV ରୁ ନୁହେଁ, absolute canvas coordinate ରୁ sample ହୁଏ। Scissor ଘୁଞ୍ଚାଇବା କେବଳ GPU କେଉଁ pixel process କରିବ ତାହା ବଦଳାଏ; ପ୍ରତ୍ୟେକ pixel grain texture ର କେଉଁ ସ୍ଥାନ ପଢ଼ିବ ତାହା ବଦଳାଏ ନାହିଁ। ତେଣୁ ପାଖପାଖି rectangle ମଧ୍ୟରେ texture seam ହୁଏ ନାହିଁ ଏବଂ canvas ଟାଣିଲେ grain ସରିଯାଏ ନାହିଁ।

କେବଳ pixel workload ଧରିଲେ, ନୂଆ work scope ପ୍ରାୟ

ଯେଉଁଠାରେ ହେଉଛି ବର୍ତ୍ତମାନ screen ଉପରେ -ତମ ଚକ୍ stroke ର axis-aligned bounding-box area। Render encoder ର ସଂଖ୍ୟା କମିନାହିଁ, କିନ୍ତୁ ପ୍ରତ୍ୟେକ clear ଓ composite ଏବେ stroke ର screen bounding box ମଧ୍ୟରେ ସୀମିତ।

ସମାନ ରଙ୍ଗର ଚକ୍ stroke ଗୁଡ଼ିକୁ ଏକ batch କାହିଁକି କରାଗଲା ନାହିଁ

ପୃଷ୍ଠାର ଅଧିକାଂଶ ଚକ୍ stroke ର ରଙ୍ଗ ଓ density ସମାନ। ତେଣୁ ଦଶଦଶଟି stroke କୁ ଏକାଥରେ scratch ରେ ଆଙ୍କି କେବଳ ଥରେ composite କରିବା ଆକର୍ଷଣୀୟ ଲାଗେ। ଏହା render pass କୁ ଆଉ କମାଇପାରେ, କିନ୍ତୁ overlap ଅଞ୍ଚଳରେ ରଙ୍ଗ ଓ grain ର ଅର୍ଥବୋଧ ବଦଳାଇଦିଏ।

ଉଦ୍ଦେଶ୍ୟପୂର୍ବକ ସରଳ କରାଯାଇଥିବା ଏକ ଉଦାହରଣ ଧରନ୍ତୁ: ଗୋଟିଏ pixel ରେ ଦୁଇଟି stroke ର grain-gate value ସମାନ , ଏବଂ ସେମାନଙ୍କ body coverage ହେଉଛି । ପ୍ରକୃତ shader ରେ gate ପ୍ରତ୍ୟେକ stroke ର pressure depth ଉପରେ ମଧ୍ୟ ନିର୍ଭର କରେ; batching ସାଧାରଣତଃ equivalent ନୁହେଁ ବୋଲି ଦେଖାଇବା ପାଇଁ ଏହି ଆହୁରି ସରଳ ଉଦାହରଣଟି ଯଥେଷ୍ଟ। ବର୍ତ୍ତମାନର per-stroke compositing ଦେଉଛି

କିନ୍ତୁ ପ୍ରଥମେ body କୁ merge କରି ତାପରେ ଗୋଟିଏ gate ଲଗାଇଲେ ମିଳେ

ଏହି ଦୁଇଟିର ତାରତମ୍ୟ । ଦୁଇଟି stroke overlap କଲେ ଏବଂ grain gate ନିର୍ମଳ zero କିମ୍ବା ନିର୍ମଳ one ନ ଥିଲେ ଫଳ ଭିନ୍ନ ହୁଏ। ସିଧାସଳଖ batch କଲେ crossing ଅଞ୍ଚଳରେ ଚକ୍ ଧୂଳି ପଡ଼ିବାର ଧାରା ବଦଳିଯିବ।

ସଠିକ୍ batching ପାଇଁ stroke pixel ଗୁଡ଼ିକ ପରସ୍ପର disjoint ବୋଲି ପ୍ରମାଣ କରିବାକୁ ପଡ଼ିବ, କିମ୍ବା ପ୍ରତ୍ୟେକ stroke ପାଇଁ ଏକ ସ୍ୱତନ୍ତ୍ର atlas region ଦେଇ ମୂଳ କ୍ରମରେ composite କରିବାକୁ ପଡ଼ିବ। ଶେଷ device acceptance ରେ scissor ପଦ୍ଧତିକୁ ରଖାଗଲା, ତେଣୁ ଏହି ପର୍ଯ୍ୟାୟରେ atlas କିମ୍ବା ତାହାକୁ ପରିଚାଳନା କରିବାର ଜଟିଳତା ଯୋଡ଼ାଯାଇନଥିଲା।

ଏକ billion pixel ଠାରୁ ପୁଣି କିଛି million pixel ପର୍ଯ୍ୟନ୍ତ

ଶେଷ device measurement ଗୁଡ଼ିକ:

ପରିସ୍ଥିତିସୁଧାର ପୂର୍ବରୁPrecise scissor
70ଟି ଦୃଶ୍ୟମାନ ଚକ୍ stroke, 300% zoom, ଲେଖିବା ସମୟରେGPU 52–60 ms≈ 9–10 ms
≈ 121ଟି ଦୃଶ୍ୟମାନ ଚକ୍ stroke, 300% zoomGPU 77–80 ms13.7–15.6 ms
ପ୍ରତି frame scratch + composite ର theoretical rectangle scope783 M–1.34 B pixels≈ 1.7 M–3 M pixels

Device document ରୁ 3,452ଟି stroke ଏବଂ 202,710ଟି sample point ନେଇ clipping boundary ମଧ୍ୟ ଯାଞ୍ଚ କଲୁ। 0.5×, 1×, 2×, 3×, 5× ଏବଂ 8× zoom ରେ 186,408ଟି viewport case ତିଆରି ହେଲା; ଯେଉଁ point sprite non-zero coverage ଦେଇପାରୁଥିଲା, ସେ ପ୍ରତ୍ୟେକଟି calculated scissor ଭିତରେ ଥିଲା। ଏହି ଯାଞ୍ଚରେ canvas edge, viewport edge ଏବଂ ବିଭିନ୍ନ offset combination ସାମିଲ ଥିଲା।

ଶେଷ code interaction state ଉପରେ ଆଧାର କରି low-resolution LOD କୁ switch କରେ ନାହିଁ। Low zoom ରେ ଏବେ ମଧ୍ୟ ସମ୍ପୂର୍ଣ୍ଣ ପୃଷ୍ଠାର ink texture ଦେଖାଯାଏ; high zoom ରେ ଦୃଶ୍ୟମାନ stroke ଗୁଡ଼ିକୁ ଏବେ ମଧ୍ୟ vector ଭାବେ redraw କରାଯାଏ। Threshold ର ଏକେ ପାର୍ଶ୍ୱରେ ପେନ୍ ଲାଗିବା କିମ୍ବା canvas ଚଳାଇବା ପୂର୍ବରୁ ଥିବା stroke କୁ ଅନ୍ୟ clarity level ରେ ବଦଳାଏ ନାହିଁ। High-zoom vector redraw ସମୟରେ ପ୍ରତ୍ୟେକ ଚକ୍ stroke ର scratch clear ଓ composite କେବଳ ନିଜ screen bounding box ମଧ୍ୟରେ ହୁଏ।

GPU time ସ୍ପଷ୍ଟତାକୁ ଧରିପାରିଲା ନାହିଁ

GPU performance problem ଗୁଡ଼ିକ data structure ର ସବୁଠାରୁ ଦେଖାଯାଉଥିବା ସଂଖ୍ୟା ସହ ଅବଶ୍ୟ ଏକେ ଭାବରେ ବଢ଼େ ନାହିଁ। ଏଠାରେ 3,571 input point ସହଜରେ ସନ୍ଦେହର କାରଣ ହୋଇପାରୁଥିଲା; କିନ୍ତୁ frame time ନିର୍ଣ୍ଣୟ କରୁଥିଲା 70ଟି ଚକ୍ stroke ଦ୍ୱାରା ଚାଲୁ ହେଉଥିବା ପୂରା-ସ୍କ୍ରିନ୍ କାମ ଏବଂ ସେମାନଙ୍କ render-pass switching।

ଦୃଶ୍ୟମାନ ଅର୍ଥବୋଧ ମଧ୍ୟ ଉପଲବ୍ଧ optimization କୁ ସୀମିତ କରିଥିଲା। ପ୍ରତ୍ୟେକ stroke ପାଇଁ ଅଲଗା scratch, ମୂଳ compositing order ଏବଂ absolute canvas grain coordinate କୁ ଇଚ୍ଛାମତେ ହଟାଇହେବ ନାହିଁ। ରଙ୍ଗ ଓ density ସମାନ ହେବାର ଅର୍ଥ କେବଳ parameter ସମାନ; overlap ଫଳାଫଳକୁ merge କରିହେବ ବୋଲି ଏହା ପ୍ରମାଣ କରେ ନାହିଁ।

ପ୍ରକୃତ device ର feedback ସବୁଠାରୁ କମ୍ GPU time ଥିବା version କୁ ଖାରଜ କଲା। “ସମ୍ପୂର୍ଣ୍ଣ canvas ଧୁସର ହୋଇଯାଏ” ବୋଲି ମିଳିଥିବା ଟିପ୍ପଣୀ measurement ଏକାକୀ ଦେଖାଇପାରିନଥିବା product constraint କୁ ସ୍ପଷ୍ଟ କଲା: Apple Pencil screen କୁ ଛୁଇଁବାବେଳେ ବ୍ୟବହାରକାରୀ ପୂର୍ବରୁ ଥିବା stroke କୁ ମଧ୍ୟ ଦେଖୁଥାନ୍ତି।

ଶେଷ version ନୂଆ interaction cache layer ଯୋଡ଼େ ନାହିଁ ଏବଂ ସ୍ପଷ୍ଟତା କମାଏ ନାହିଁ। High-zoom vector redraw କେବଳ ପ୍ରତ୍ୟେକ ଚକ୍ stroke ର କାମକୁ ତାହାର ନିଜ screen bounding box ମଧ୍ୟରେ ସୀମିତ କରେ। LucasPad ରେ ପୁଣି load କରିବା ପରେ feedback ଥିଲା: “ବହୁତ ଭଲ ଲାଗୁଛି।”