จำเป็นต้องมีการบัฟเฟอร์สองเท่าเมื่อเปิดใช้งานองค์ประกอบเดสก์ท็อปหรือไม่

ยังจำเป็นต้องมีการบัฟเฟอร์สองเท่าเมื่อเปิดใช้งานองค์ประกอบเดสก์ท็อปหรือไม่

ในคู่มือความเข้ากันได้ของแอปพลิเคชันของ Microsoft:

อินเทอร์เฟซอุปกรณ์กราฟิก (GDI)

ก่อน Windows Vista และ Windows Server 2008 ตัวจัดการหน้าต่าง (HWND) ได้รับการทาสีลงบนหน้าจอโดยตรง ซึ่งมีประโยชน์บางประการ แต่จำกัดวิธีที่ Windows สามารถแสดงและจัดการหน้าต่างระดับบนสุดได้ ใน Windows Vista และ Windows Server 2008 หน้าต่างระดับบนสุดทั้งหมดจะแสดงผลเป็นบิตแมปนอกหน้าจอ (คล้ายกับ WS_EX_LAYERED) และ Desktop Window Manager จะรวมรูปภาพเข้าด้วยกันเพื่อวาดภาพเดสก์ท็อป

ดูเหมือนว่าตอนนี้การเรนเดอร์ทั้งหมดเสร็จสิ้นแล้วกับบิตแมปนอกหน้าจอ:

windows ถูกเรนเดอร์เป็นบิตแมปนอกหน้าจอ

สิ่งนี้ถูกต้องหรือไม่?

เหตุผลที่ฉันถามเพราะฉันยังคงเห็นการกะพริบระหว่างรอบการทาสีมาตรฐาน:

  • WM_ERASEBKGND
  • WM_PAINT

ในขณะที่เปิดใช้งานองค์ประกอบเดสก์ท็อป:

ข้อความแสดงแทน

ฉันจะสันนิษฐานว่าระหว่างการโทรไปที่

   BeginPaint(hWnd, paintStructure);
   ...
   EndPaint(hWnd, paintStructure);

การทาสีทั้งหมดจะเกิดขึ้นกับบัฟเฟอร์ด้านหลัง:

windows ถูกเรนเดอร์เป็นบิตแมปนอกหน้าจอ

ในขณะเดียวกันบัฟเฟอร์ด้านหน้าก็จะไม่ได้รับผลกระทบ


person Ian Boyd    schedule 03.12.2009    source แหล่งที่มา


คำตอบ (3)


สิ่งนี้ถูกต้องหรือไม่?

ได้ (ซึ่งเป็นวิธีที่ภาพขนาดย่อสามารถแสดงให้คุณเห็นบางส่วนของหน้าต่างที่ถูกบดบังอยู่ในปัจจุบัน)

การเรนเดอร์หน้าจอของ DWM เป็นแบบบัฟเฟอร์สองเท่า อย่างไรก็ตาม ถ้ามันไปคว้าบัฟเฟอร์ของคุณระหว่างการลบและการวาดภาพ... มันจะปรากฏเป็นสิ่งประดิษฐ์ที่มองเห็นได้ ดังนั้นคุณยังคงต้องบัฟเฟอร์สองเท่า การบัฟเฟอร์สองครั้งเกิดขึ้นบนเดสก์ท็อป (เช่น ดึงมุมมองเดสก์ท็อปถัดไปอย่างสมบูรณ์แล้วจึงพลิก) ไม่ใช่บนบัฟเฟอร์นอกหน้าจอที่แต่ละหน้าต่างถูกดึงเข้าไป

person DrPizza    schedule 03.12.2009
comment
คุณทั้งสองชี้ให้เห็นสิ่งเดียวกัน: ซึ่งอาจทำให้เป็นคำตอบที่ถูกต้อง ฉันวาดภาพลงบนบัฟเฟอร์ที่ใช้สำหรับการทาสีโดยตรง หาก DWM คว้าบัฟเฟอร์นั้นในขณะที่ฉันกำลังทาสีครึ่งหนึ่ง ฉันจะเห็นเนื้อหาที่ทาสีครึ่งหนึ่ง - person Ian Boyd; 04.12.2009

การวาดภาพบิตแมปนอกหน้าจอช่วยให้ DWM สามารถรวมหน้าต่างได้ตามต้องการโดยไม่ต้องรอให้แอปพลิเคชันวาดใหม่ (เช่นในกรณีของ XP เมื่อคุณย้ายหน้าต่างไปไว้เหนือหน้าต่างอื่น เป็นต้น)

นี่ ไม่ หมายความว่าการวาดลงบนพื้นผิวนอกหน้าจอจะลดการกะพริบโดยอัตโนมัติ หากคุณลบหน้าต่างแล้ววาดใหม่ และระหว่างการกระทำทั้งสอง DWM จะวาดหน้าจอใหม่ (ซึ่งเกิดขึ้นประมาณ 60 ครั้งต่อวินาที) แน่นอนว่าคุณจะเห็นการกะพริบ

จะช่วยแก้ปัญหา "หน้าต่างสีขาว" เมื่อแอปพลิเคชันวาดไม่เร็วพอ และยังช่วยลดการวาดใหม่เนื่องจากหน้าต่างทับซ้อนกัน แต่ไม่ได้ช่วยเรื่องการริบหรี่ DWM ไม่มีทางรู้ได้ว่าการดำเนินการระบายสีของคุณยังไม่เสร็จสมบูรณ์ และคุณต้องการให้แสดงรูปภาพเก่าของหน้าต่างจนกว่าคุณจะวาดเนื้อหาอีกครั้ง

person Joey    schedule 03.12.2009
comment
เนื่องจากการวาดภาพบน windows นั้นอยู่ระหว่างการเรียก BeginPaint และ EndPaint เป็นอย่างดี คุณคงคิดว่า DWM สามารถ รู้ได้ว่าเมื่อใดจึงจะสามารถรับการอัปเดตได้อย่างปลอดภัย - person Chris Becke; 09.02.2010
comment
มันก็ต้องติดตามเรื่องนี้ต่อไป ฉันสงสัยว่าการพิจารณาประสิทธิภาพนั้นอยู่เหนือเนื้อหาที่ลงสีเพียงครึ่งเดียว - person Joey; 09.02.2010
comment
@Chris: ไม่มีข้อกำหนดสำหรับแอปพลิเคชันที่จะโทร BeginPaint และ EndPaint คุณกำลังอธิบายว่าระบบสามารถนำไปใช้ในโลกที่สมบูรณ์แบบได้อย่างไร โลกนี้ไม่ใช่.. - person IInspectable; 15.05.2015
comment
ทุกอย่างจะค่อนข้างไปด้านข้างถ้าคุณไม่เรียก BeginPaint / EndPaint เพื่อตอบสนองต่อ WM_PAINT - person Chris Becke; 15.05.2015
comment
@Chris: ไม่ พวกเขาทำไม่ได้ ตราบใดที่คุณแน่ใจว่าได้ตรวจสอบขอบเขตที่สกปรกแล้ว ผ่านการเรียกไปที่ ValidateRect< /ก>. - person IInspectable; 15.05.2015

สิ่งนี้มีการเปลี่ยนแปลงใน Windows 10 (อย่างน้อยปี 1903)

เมื่อเปิดใช้งาน DWM ทุกอย่างจะถูกบัฟเฟอร์สองเท่าอย่างถูกต้องตามค่าเริ่มต้น ไม่มีการสั่นไหวในการทาสีใหม่/ปรับขนาด แม้ว่าจะย้ายและปรับขนาดส่วนควบคุมด้วยวิธีพื้นฐานที่สุดก็ตาม

ขณะนี้ DWM ดูเหมือนจะนำเสนอบิตแมปใหม่เมื่อการวาดภาพเสร็จสิ้นเท่านั้น ไม่ใช่ก่อนหน้านี้

person Leo Davidson    schedule 25.10.2019
comment
DWM รู้ได้อย่างไรว่าการทาสีบางส่วนเสร็จสิ้นแล้ว? ฉันอยากรู้อยากเห็น ฉันคิดว่ามันจะต้องเป็นสิ่งที่ EndPaint จะทำ - แม้ว่าแอปพลิเคชันที่ไม่ได้ใช้ EndPaint (ซึ่งมีมากมายมากไม่ว่าจะดีขึ้นหรือแย่ลง) ก็จะถูก DWM ใช้งานไม่ได้ หรือบางที DWM รู้ว่าการทาสีบางส่วนเสร็จสิ้นแล้วเมื่อมีการเรียกโพรซีเดอร์ของหน้าต่างกลับมาหลังจากส่งผ่าน WM_PAINT? หรือบางทีเมื่อ ReleaseDC ถูกเรียก (ซึ่งอีกครั้งจะทำให้แอปพลิเคชั่นจำนวนหนึ่งที่ยึด DC ของพวกเขาไว้)? - person amn; 25.06.2021