อัตราเฟรม

Frame Rate API ช่วยให้แอปแจ้งแพลตฟอร์ม Android เกี่ยวกับอัตราเฟรมที่ต้องการได้ และพร้อมใช้งานในแอปที่กำหนดเป้าหมายเป็น Android 11 (API ระดับ 30) ขึ้นไป เดิมทีอุปกรณ์ส่วนใหญ่รองรับอัตราการรีเฟรชของจอแสดงผลเพียงอัตราเดียว ซึ่งมักจะเป็น 60 Hz แต่ตอนนี้มีการเปลี่ยนแปลงแล้ว ปัจจุบันอุปกรณ์จำนวนมากรองรับอัตราการรีเฟรชเพิ่มเติม เช่น 90 Hz หรือ 120 Hz อุปกรณ์บางเครื่องรองรับการเปลี่ยนอัตราการรีเฟรชที่ราบรื่น ขณะที่อุปกรณ์อื่นๆ จะแสดงหน้าจอสีดําเป็นระยะเวลาสั้นๆ ซึ่งมักจะใช้เวลาประมาณ 1 วินาที

วัตถุประสงค์หลักของ API คือช่วยให้แอปใช้ประโยชน์จากอัตราการรีเฟรชของจอแสดงผลที่รองรับทั้งหมดได้ดียิ่งขึ้น ตัวอย่างเช่น แอปที่เล่นวิดีโอ 24Hz ซึ่งเรียก setFrameRate() อาจส่งผลให้อุปกรณ์เปลี่ยนอัตราการรีเฟรชของจอแสดงผลจาก 60Hz เป็น 120Hz ความถี่รีเฟรชใหม่นี้ช่วยให้เล่นวิดีโอ 24Hz ได้ราบรื่นและไม่มีภาพกระตุก โดยไม่จำเป็นต้องใช้การลดขนาดภาพ 3:2 ที่จำเป็นสำหรับการเล่นวิดีโอเดียวกันบนจอแสดงผล 60Hz ซึ่งส่งผลให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดียิ่งขึ้น

การใช้งานพื้นฐาน

Android มีวิธีต่างๆ ในการเข้าถึงและควบคุมแพลตฟอร์ม จึงมี setFrameRate() API หลายเวอร์ชัน API แต่ละเวอร์ชันใช้พารามิเตอร์เดียวกันและทํางานเหมือนกับเวอร์ชันอื่นๆ ดังนี้

แอปไม่จำเป็นต้องพิจารณาอัตราการรีเฟรชของจอแสดงผลที่รองรับจริง ซึ่งสามารถรับได้โดยเรียกใช้ Display.getSupportedModes() เพื่อเรียกใช้ setFrameRate() อย่างปลอดภัย เช่น แม้ว่าอุปกรณ์จะรองรับเพียง 60Hz แต่ให้เรียกใช้ setFrameRate() ด้วยอัตราเฟรมที่แอปต้องการ อุปกรณ์ที่ไม่มีอัตราการรีเฟรชที่เหมาะกับอัตราเฟรมของแอปมากกว่าจะใช้อัตราการรีเฟรชของจอแสดงผลปัจจุบันต่อไป

หากต้องการดูว่าการเรียกใช้ setFrameRate() ส่งผลให้อัตราการรีเฟรชของจอแสดงผลเปลี่ยนแปลงหรือไม่ ให้ลงทะเบียนรับการแจ้งเตือนการเปลี่ยนแปลงของจอแสดงผลโดยเรียกใช้ DisplayManager.registerDisplayListener() หรือ AChoreographer_registerRefreshRateCallback()

เมื่อเรียกใช้ setFrameRate() คุณควรส่งอัตราเฟรมที่แน่นอนแทนที่จะปัดเศษเป็นจำนวนเต็ม เช่น เมื่อแสดงผลวิดีโอที่บันทึกที่ 29.97Hz ให้ส่ง 29.97 แทนที่จะปัดเศษเป็น 30

สําหรับแอปวิดีโอ ควรตั้งค่าพารามิเตอร์ความเข้ากันได้ที่ส่งไปยัง setFrameRate() เป็น Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE เพื่อให้คำแนะนำเพิ่มเติมแก่แพลตฟอร์ม Android ว่าแอปจะใช้การเลื่อนลงเพื่อปรับให้เข้ากับอัตราการรีเฟรชของจอแสดงผลที่ไม่ตรงกัน (ซึ่งจะส่งผลให้ภาพกระตุก)

ในบางสถานการณ์ แพลตฟอร์มวิดีโอจะหยุดส่งเฟรมแต่จะยังคงปรากฏบนหน้าจอต่อไปอีกระยะหนึ่ง สถานการณ์ที่พบบ่อย ได้แก่ เมื่อการเล่นจบลงหรือเมื่อผู้ใช้หยุดเล่นชั่วคราว ในกรณีเหล่านี้ ให้เรียกใช้ setFrameRate() โดยตั้งค่าพารามิเตอร์อัตราเฟรมเป็น 0 เพื่อล้างการตั้งค่าอัตราเฟรมของพื้นผิวกลับเป็นค่าเริ่มต้น คุณไม่จำเป็นต้องล้างการตั้งค่าอัตราเฟรมเช่นนี้เมื่อทำลายแพลตฟอร์มหรือเมื่อแพลตฟอร์มซ่อนอยู่เนื่องจากผู้ใช้เปลี่ยนไปใช้แอปอื่น ให้ล้างการตั้งค่าอัตราเฟรมเฉพาะในกรณีที่แพลตฟอร์มยังคงมองเห็นได้อยู่แต่ไม่มีการใช้งาน

การเปลี่ยนอัตราเฟรมที่ไม่ราบรื่น

ในอุปกรณ์บางรุ่น การสลับอัตราการรีเฟรชอาจมีการหยุดชะงักของภาพ เช่น หน้าจอเป็นสีดําเป็นเวลา 1-2 วินาที ปัญหานี้มักเกิดขึ้นในกล่องรับสัญญาณ แผงทีวี และอุปกรณ์ที่คล้ายกัน โดยค่าเริ่มต้น เฟรมเวิร์ก Android จะไม่เปลี่ยนโหมดเมื่อมีการเรียกใช้ Surface.setFrameRate() API เพื่อหลีกเลี่ยงการขัดจังหวะภาพดังกล่าว

ผู้ใช้บางรายชอบโฆษณาคั่นระหว่างหน้าในช่วงต้นและท้ายของวิดีโอที่ยาว วิธีนี้ช่วยให้อัตราการรีเฟรชของจอแสดงผลตรงกับอัตราเฟรมของวิดีโอ และหลีกเลี่ยงข้อบกพร่องในการแปลงอัตราเฟรม เช่น การสั่นของภาพแบบ 3:2 ในการเลื่อนลงเพื่อเล่นภาพยนตร์

ด้วยเหตุนี้ คุณจึงเปิดใช้การเปลี่ยนอัตราการรีเฟรชแบบไม่ราบรื่นได้หากทั้งผู้ใช้และแอปเลือกใช้ โดยทำดังนี้

เราขอแนะนำให้ใช้ CHANGE_FRAME_RATE_ALWAYS เสมอสำหรับวิดีโอที่มีความยาว เช่น ภาพยนตร์ เนื่องจากประโยชน์ของการจับคู่อัตราเฟรมวิดีโอมีมากกว่าการหยุดชะงักที่เกิดขึ้นเมื่อเปลี่ยนอัตราการรีเฟรช

คำแนะนำเพิ่มเติม

ทำตามคำแนะนำต่อไปนี้สำหรับสถานการณ์ที่พบบ่อย

พื้นผิวหลายประเภท

แพลตฟอร์ม Android ออกแบบมาเพื่อจัดการสถานการณ์ที่มีแพลตฟอร์มหลายแพลตฟอร์มที่มีการตั้งค่าอัตราเฟรมแตกต่างกันอย่างถูกต้อง เมื่อแอปมีแพลตฟอร์มหลายแพลตฟอร์มที่มีอัตราเฟรมแตกต่างกัน ให้เรียกใช้ setFrameRate() ด้วยอัตราเฟรมที่ถูกต้องสำหรับแต่ละแพลตฟอร์ม แม้ว่าอุปกรณ์จะใช้งานแอปหลายแอปพร้อมกันโดยใช้โหมดแยกหน้าจอหรือภาพซ้อนภาพ แอปแต่ละแอปก็สามารถเรียกsetFrameRate()สำหรับแพลตฟอร์มของตนเองได้อย่างปลอดภัย

แพลตฟอร์มจะไม่เปลี่ยนเป็นอัตราเฟรมของแอป

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

ทั้งนี้แอปจะเป็นผู้ตัดสินใจว่าจะตอบสนองอย่างไรเมื่ออัตราการรีเฟรชของจอแสดงผลไม่ตรงกับอัตราเฟรมของแอป สำหรับวิดีโอ อัตราเฟรมจะคงที่ตามอัตราเฟรมของวิดีโอต้นฉบับ และจะต้องมีการเลื่อนลงเพื่อแสดงเนื้อหาวิดีโอ เกมอาจเลือกที่จะพยายามทำงานที่อัตราการรีเฟรชของจอแสดงผลแทนที่จะใช้อัตราเฟรมที่ต้องการ แอปไม่ควรเปลี่ยนแปลงค่าที่ส่งไปยัง setFrameRate() โดยอิงตามสิ่งที่แพลตฟอร์มทํา โดยควรตั้งค่าเป็นอัตราเฟรมที่ต้องการของแอป ไม่ว่าแอปจะจัดการกับกรณีที่แพลตฟอร์มไม่ปรับให้ตรงกับคำขอของแอปอย่างไรก็ตาม วิธีนี้ช่วยให้แพลตฟอร์มมีข้อมูลที่ถูกต้องในการเปลี่ยนไปใช้อัตราเฟรมที่ต้องการของแอปได้ หากสภาพของอุปกรณ์เปลี่ยนแปลงไปเพื่อให้ใช้อัตราการรีเฟรชของจอแสดงผลเพิ่มเติมได้

ในกรณีที่แอปไม่ทำงานหรือทำงานไม่ได้ที่อัตราการรีเฟรชของจอแสดงผล แอปควรระบุการประทับเวลาของการแสดงสำหรับแต่ละเฟรมโดยใช้กลไกการตั้งค่าการประทับเวลาของการแสดงผลอย่างใดอย่างหนึ่งต่อไปนี้ของแพลตฟอร์ม

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

ในบางกรณี แพลตฟอร์มอาจเปลี่ยนไปใช้อัตราเฟรมที่คูณกับอัตราเฟรมที่แอประบุไว้ใน setFrameRate() เช่น แอปอาจเรียก setFrameRate() ด้วย 60Hz และอุปกรณ์อาจเปลี่ยนการแสดงผลเป็น 120Hz สาเหตุหนึ่งที่ทำให้ปัญหานี้เกิดขึ้นอาจเป็นเพราะแอปอื่นมีพื้นผิวที่มีการตั้งค่าอัตราเฟรมเป็น 24Hz ในกรณีนี้ การแสดงผลที่ 120Hz จะช่วยให้ทั้งพื้นผิว 60Hz และ 24Hz ทำงานได้โดยไม่ต้องมีการดึงลง

เมื่อจอแสดงผลทำงานด้วยอัตราเฟรมที่มากกว่าอัตราเฟรมของแอป แอปควรระบุการประทับเวลาของการแสดงผลสำหรับแต่ละเฟรมเพื่อหลีกเลี่ยงการกระตุกที่ไม่จำเป็น สำหรับเกม ไลบรารี Frame Pacing ของ Android จะช่วยในการตั้งค่าการประทับเวลาของการแสดงเฟรมอย่างถูกต้อง

setFrameRate() เทียบกับ preferredDisplayModeId

WindowManager.LayoutParams.preferredDisplayModeId เป็นอีกวิธีหนึ่งที่แอปใช้ระบุอัตราเฟรมของตนไปยังแพลตฟอร์ม แอปบางแอปต้องการเปลี่ยนเฉพาะอัตราการรีเฟรชของจอแสดงผล แทนที่จะเปลี่ยนการตั้งค่าโหมดการแสดงผลอื่นๆ เช่น ความละเอียดของจอแสดงผล โดยทั่วไป ให้ใช้ setFrameRate() แทน preferredDisplayModeId ฟังก์ชัน setFrameRate() ใช้งานได้ง่ายกว่าเนื่องจากแอปไม่จําเป็นต้องค้นหารายการโหมดการแสดงผลเพื่อหาโหมดที่มีอัตราเฟรมที่เฉพาะเจาะจง

setFrameRate() ช่วยให้แพลตฟอร์มมีโอกาสเลือกอัตราเฟรมที่เข้ากันได้มากขึ้นในสถานการณ์ที่มีแพลตฟอร์มหลายรายการที่ทำงานด้วยอัตราเฟรมที่แตกต่างกัน ตัวอย่างเช่น ลองนึกถึงกรณีที่แอป 2 แอปทำงานในโหมดแยกหน้าจอบน Pixel 4 โดยแอปหนึ่งเล่นวิดีโอ 24Hz และอีกแอปหนึ่งแสดงรายการที่เลื่อนได้แก่ผู้ใช้ Pixel 4 รองรับอัตราการรีเฟรชของจอแสดงผล 2 แบบ ได้แก่ 60 Hz และ 90 Hz เมื่อใช้ preferredDisplayModeId API ระบบจะบังคับให้แพลตฟอร์มวิดีโอเลือก 60Hz หรือ 90Hz การเรียกใช้ setFrameRate() ด้วย 24Hz จะทำให้แพลตฟอร์มได้รับข้อมูลเพิ่มเติมเกี่ยวกับอัตราเฟรมของวิดีโอต้นทาง ซึ่งช่วยให้แพลตฟอร์มเลือก 90Hz เป็นอัตราการรีเฟรชของจอแสดงผลได้ ซึ่งดีกว่า 60Hz ในสถานการณ์นี้

อย่างไรก็ตาม ก็มีบางกรณีที่ควรใช้ preferredDisplayModeId แทน setFrameRate() เช่น ต่อไปนี้

  • หากแอปต้องการเปลี่ยนความละเอียดหรือการตั้งค่าโหมดการแสดงผลอื่นๆ ให้ใช้ preferredDisplayModeId
  • แพลตฟอร์มจะเปลี่ยนโหมดการแสดงผลเพื่อตอบสนองต่อการเรียกใช้setFrameRate()ก็ต่อเมื่อการเปลี่ยนโหมดนั้นเบาและไม่น่าจะสังเกตเห็นได้โดยผู้ใช้ หากแอปต้องการเปลี่ยนอัตราการรีเฟรชของจอแสดงผลแม้ว่าจะต้องสลับโหมดที่หนัก (เช่น ในอุปกรณ์ Android TV) ให้ใช้ preferredDisplayModeId
  • แอปที่จัดการการแสดงผลที่ทำงานด้วยอัตราเฟรมหลายเท่าของแอปไม่ได้ ซึ่งกำหนดให้ต้องตั้งค่าการประทับเวลาของการแสดงในแต่ละเฟรม ควรใช้ preferredDisplayModeId

setFrameRate() เทียบกับ preferredRefreshRate

WindowManager.LayoutParams#preferredRefreshRate ตั้งค่าอัตราเฟรมที่ต้องการในหน้าต่างของแอป และอัตราดังกล่าวจะมีผลกับแพลตฟอร์มทั้งหมดภายในหน้าต่าง แอปควรระบุอัตราเฟรมที่ต้องการโดยไม่คำนึงถึงอัตราการรีเฟรชที่อุปกรณ์รองรับ ซึ่งคล้ายกับsetFrameRate() เพื่อให้ตัวจัดตารางมีข้อมูลคร่าวๆ ที่ดีขึ้นเกี่ยวกับอัตราเฟรมที่ต้องการของแอป

ระบบจะไม่สนใจ preferredRefreshRate สำหรับ Surface ที่ใช้ setFrameRate() โดยทั่วไป ให้ใช้ setFrameRate() หากเป็นไปได้

preferredRefreshRate เทียบกับ preferredDisplayModeId

หากแอปต้องการเปลี่ยนเฉพาะอัตราการรีเฟรชที่ต้องการ เราขอแนะนำให้ใช้ preferredRefreshRate แทน preferredDisplayModeId

หลีกเลี่ยงการเรียก setFrameRate() บ่อยเกินไป

แม้ว่าการเรียก setFrameRate() จะไม่ส่งผลเสียต่อประสิทธิภาพมากนัก แต่แอปควรหลีกเลี่ยงการเรียก setFrameRate() ทุกเฟรมหรือหลายครั้งต่อวินาที การเรียกใช้ setFrameRate() มีแนวโน้มที่จะส่งผลให้อัตราการรีเฟรชของจอแสดงผลเปลี่ยนแปลง ซึ่งอาจส่งผลให้เฟรมลดลงในระหว่างการเปลี่ยน คุณควรคำนวณอัตราเฟรมที่ถูกต้องล่วงหน้าและเรียกใช้ setFrameRate() 1 ครั้ง

การใช้งานสำหรับเกมหรือแอปอื่นๆ ที่ไม่ใช่วิดีโอ

แม้ว่าวิดีโอจะเป็น Use Case หลักของ setFrameRate() API แต่ก็สามารถนำไปใช้กับแอปอื่นๆ ได้ ตัวอย่างเช่น เกมที่ตั้งใจจะไม่ทำงานที่ความถี่สูงกว่า 60Hz (เพื่อลดการใช้พลังงานและทำให้เซสชันการเล่นนานขึ้น) สามารถเรียกใช้ Surface.setFrameRate(60, Surface.FRAME_RATE_COMPATIBILITY_DEFAULT) ได้ วิธีนี้จะทำให้อุปกรณ์ที่ทำงานด้วย 90Hz โดยค่าเริ่มต้นจะทำงานด้วย 60Hz แทนขณะที่เกมทำงานอยู่ ซึ่งจะช่วยหลีกเลี่ยงการกระตุกที่อาจเกิดขึ้นหากเกมทำงานด้วย 60Hz ขณะที่จอแสดงผลทำงานด้วย 90Hz

การใช้ FRAME_RATE_COMPATIBILITY_FIXED_SOURCE

FRAME_RATE_COMPATIBILITY_FIXED_SOURCE มีไว้สำหรับแอปวิดีโอเท่านั้น สำหรับการใช้งานที่ไม่ใช่วิดีโอ ให้ใช้ FRAME_RATE_COMPATIBILITY_DEFAULT

การเลือกกลยุทธ์ในการเปลี่ยนอัตราเฟรม

  • เราขอแนะนําอย่างยิ่งว่าเมื่อแสดงวิดีโอที่มีระยะเวลานาน เช่น ภาพยนตร์ แอปควรเรียกใช้ setFrameRate(fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, CHANGE_FRAME_RATE_ALWAYS) โดยที่ fps คืออัตราเฟรมของวิดีโอ
  • เราขอแนะนำอย่างยิ่งไม่ให้แอปเรียก setFrameRate() ด้วย CHANGE_FRAME_RATE_ALWAYS เมื่อคุณคาดว่าการเล่นวิดีโอจะใช้เวลาไม่เกิน 2-3 นาที

ตัวอย่างการผสานรวมสําหรับแอปเล่นวิดีโอ

เราขอแนะนําให้ทําตามขั้นตอนต่อไปนี้เพื่อผสานรวมสวิตช์อัตรารีเฟรชในแอปการเล่นวิดีโอ

  1. กำหนด changeFrameRateStrategy ดังนี้
    1. หากเล่นวิดีโอที่มีความยาว เช่น ภาพยนตร์ ให้ใช้ MATCH_CONTENT_FRAMERATE_ALWAYS
    2. หากเล่นวิดีโอสั้น เช่น ตัวอย่างภาพยนตร์ ให้ใช้ CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS
  2. หาก changeFrameRateStrategy เป็น CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS ให้ไปที่ขั้นตอนที่ 4
  3. ตรวจหาว่ากำลังจะมีการสลับอัตราการรีเฟรชแบบไม่ราบรื่นหรือไม่โดยตรวจสอบว่าข้อเท็จจริงทั้ง 2 ข้อต่อไปนี้เป็นจริง
    1. การเปลี่ยนโหมดแบบราบรื่นจากอัตราการรีเฟรชปัจจุบัน (สมมติว่า C) เป็นอัตราเฟรมของวิดีโอ (สมมติว่า V) เป็นไปไม่ได้ กรณีนี้จะเกิดขึ้นเมื่อ C และ V ไม่เหมือนกัน และ Display.getMode().getAlternativeRefreshRates ไม่มีตัวคูณของ V
    2. ผู้ใช้เลือกใช้การเปลี่ยนแปลงอัตราการรีเฟรชแบบไม่ราบรื่น คุณสามารถตรวจหาสิ่งนี้ได้โดยดูว่า DisplayManager.getMatchContentFrameRateUserPreference แสดงผลเป็น MATCH_CONTENT_FRAMERATE_ALWAYS หรือไม่
  4. หากต้องการเปลี่ยนบัญชีอย่างราบรื่น ให้ทำดังนี้
    1. เรียกใช้ setFrameRate แล้วส่ง fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE และ changeFrameRateStrategy โดยที่ fps คืออัตราเฟรมของวิดีโอ
    2. เริ่มเล่นวิดีโอ
  5. หากการเปลี่ยนแปลงโหมดแบบไม่ราบรื่นกำลังจะเกิดขึ้น ให้ทำดังนี้
    1. แสดง UX เพื่อแจ้งให้ผู้ใช้ทราบ โปรดทราบว่าเราขอแนะนำให้คุณใช้วิธีให้ผู้ใช้ปิด UX นี้และข้ามการหน่วงเวลาเพิ่มเติมในขั้นตอนที่ 5.d เนื่องจากความล่าช้าที่เราแนะนำนั้นนานกว่าที่จำเป็นสำหรับจอแสดงผลที่มีเวลาในการสลับเร็วกว่า
    2. เรียกใช้ setFrameRate แล้วส่ง fps, FRAME_RATE_COMPATIBILITY_FIXED_SOURCE และ CHANGE_FRAME_RATE_ALWAYS โดยที่ fps คืออัตราเฟรมของวิดีโอ
    3. รอการติดต่อกลับจาก onDisplayChanged
    4. รอ 2 วินาทีเพื่อให้การเปลี่ยนโหมดเสร็จสมบูรณ์
    5. เริ่มเล่นวิดีโอ

รหัสจำลองเพื่อรองรับเฉพาะการเปลี่ยนอย่างราบรื่นมีดังนี้

SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
transaction.setFrameRate(surfaceControl,
    contentFrameRate,
    FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
    CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
transaction.apply();
beginPlayback();

รหัสจำลองเพื่อรองรับการเปลี่ยนแบบราบรื่นและไม่ราบรื่นตามที่อธิบายไว้ข้างต้นมีดังนี้

SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
if (isSeamlessSwitch(contentFrameRate)) {
  transaction.setFrameRate(surfaceControl,
      contentFrameRate,
      FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
      CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
  transaction.apply();
  beginPlayback();
} else if (displayManager.getMatchContentFrameRateUserPreference()
      == MATCH_CONTENT_FRAMERATE_ALWAYS) {
  showRefreshRateSwitchUI();
  sleep(shortDelaySoUserSeesUi);
  displayManager.registerDisplayListener(…);
  transaction.setFrameRate(surfaceControl,
      contentFrameRate,
      FRAME_RATE_COMPATIBILITY_FIXED_SOURCE,
      CHANGE_FRAME_RATE_ALWAYS);
  transaction.apply();
  waitForOnDisplayChanged();
  sleep(twoSeconds);
  hideRefreshRateSwitchUI();
  beginPlayback();
}