Kaydet (Commit) 9c218858 authored tarafından Ashod Nakashian's avatar Ashod Nakashian Kaydeden (comit) Ashod Nakashian

Lok: correct tile invalidation merging

Rectangles that are empty (i.e. IsEmpty() returns true)
were incorrectly considered to mean equivalent to "EMPTY".
The latter means full-area, while the former mean zero-area.

This fixes the issue by restrict full-area to rectangles
with 2 billion units on the each side (roughly INT_MAX) or
more, and using this new check rather than IsEmpty().

Change-Id: I12aca17267f5dd33b2932012d1d9db3545f9af6f
Reviewed-on: https://gerrit.libreoffice.org/31458Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarAshod Nakashian <ashnakash@gmail.com>
üst cd43959e
...@@ -94,6 +94,7 @@ public: ...@@ -94,6 +94,7 @@ public:
void testContextMenuWriter(); void testContextMenuWriter();
void testContextMenuImpress(); void testContextMenuImpress();
void testNotificationCompression(); void testNotificationCompression();
void testTileInvalidationCompression();
void testPartInInvalidation(); void testPartInInvalidation();
void testRedlineWriter(); void testRedlineWriter();
void testTrackChanges(); void testTrackChanges();
...@@ -127,6 +128,7 @@ public: ...@@ -127,6 +128,7 @@ public:
CPPUNIT_TEST(testContextMenuWriter); CPPUNIT_TEST(testContextMenuWriter);
CPPUNIT_TEST(testContextMenuImpress); CPPUNIT_TEST(testContextMenuImpress);
CPPUNIT_TEST(testNotificationCompression); CPPUNIT_TEST(testNotificationCompression);
CPPUNIT_TEST(testTileInvalidationCompression);
CPPUNIT_TEST(testPartInInvalidation); CPPUNIT_TEST(testPartInInvalidation);
CPPUNIT_TEST(testRedlineWriter); CPPUNIT_TEST(testRedlineWriter);
CPPUNIT_TEST(testTrackChanges); CPPUNIT_TEST(testTrackChanges);
...@@ -1372,6 +1374,33 @@ void DesktopLOKTest::testNotificationCompression() ...@@ -1372,6 +1374,33 @@ void DesktopLOKTest::testNotificationCompression()
CPPUNIT_ASSERT_EQUAL(std::string(".uno:AssignLayout=1"), std::get<1>(notifs[i++])); CPPUNIT_ASSERT_EQUAL(std::string(".uno:AssignLayout=1"), std::get<1>(notifs[i++]));
} }
void DesktopLOKTest::testTileInvalidationCompression()
{
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
std::vector<std::tuple<int, std::string>> notifs;
std::unique_ptr<CallbackFlushHandler> handler(new CallbackFlushHandler(pDocument, callbackCompressionTest, &notifs));
comphelper::LibreOfficeKit::setPartInInvalidation(true);
comphelper::ScopeGuard aGuard([]()
{
comphelper::LibreOfficeKit::setPartInInvalidation(false);
});
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 2147483767, 2147483767, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, 239, 239, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "-121, -121, 300, 300, 0");
handler->queue(LOK_CALLBACK_INVALIDATE_TILES, "0, 0, -32767, -32767, 0");
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), notifs.size());
size_t i = 0;
CPPUNIT_ASSERT_EQUAL((int)LOK_CALLBACK_INVALIDATE_TILES, (int)std::get<0>(notifs[i]));
CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 2147483767, 2147483767, 0"), std::get<1>(notifs[i++]));
}
void DesktopLOKTest::testPartInInvalidation() void DesktopLOKTest::testPartInInvalidation()
{ {
LibLODocument_Impl* pDocument = loadDoc("blank_text.odt"); LibLODocument_Impl* pDocument = loadDoc("blank_text.odt");
......
...@@ -361,11 +361,20 @@ struct RectangleAndPart ...@@ -361,11 +361,20 @@ struct RectangleAndPart
return ss.str().c_str(); return ss.str().c_str();
} }
/// Infinite Rectangle is when both dimensions are >= 2e7.
// ~2 billion twips is INT_MAX, which is full-area.
bool isInfinite() const
{
return m_aRectangle.GetWidth() >= 2e7 &&
m_aRectangle.GetHeight() >= 2e7;
}
static RectangleAndPart Create(const std::string& rPayload) static RectangleAndPart Create(const std::string& rPayload)
{ {
RectangleAndPart aRet; RectangleAndPart aRet;
if (rPayload.find("EMPTY") == 0) // payload starts with "EMPTY" if (rPayload.find("EMPTY") == 0) // payload starts with "EMPTY"
{ {
aRet.m_aRectangle = Rectangle(0, 0, INT_MAX, INT_MAX);
if (comphelper::LibreOfficeKit::isPartInInvalidation()) if (comphelper::LibreOfficeKit::isPartInInvalidation())
aRet.m_nPart = std::stol(rPayload.substr(6)); aRet.m_nPart = std::stol(rPayload.substr(6));
...@@ -678,9 +687,9 @@ void CallbackFlushHandler::queue(const int type, const char* data) ...@@ -678,9 +687,9 @@ void CallbackFlushHandler::queue(const int type, const char* data)
{ {
RectangleAndPart rcOld = RectangleAndPart::Create(pos->second); RectangleAndPart rcOld = RectangleAndPart::Create(pos->second);
RectangleAndPart rcNew = RectangleAndPart::Create(payload); RectangleAndPart rcNew = RectangleAndPart::Create(payload);
if (rcOld.m_aRectangle.IsEmpty() && rcOld.m_nPart == rcNew.m_nPart) if (rcOld.isInfinite() && rcOld.m_nPart == rcNew.m_nPart)
{ {
//SAL_WARN("lok", "Skipping queue [" + std::to_string(type) + "]: [" + payload + "] since all tiles need to be invalidated."); SAL_WARN("lok", "Skipping queue [" << type << "]: [" << payload << "] since all tiles need to be invalidated.");
return; return;
} }
} }
...@@ -767,8 +776,9 @@ void CallbackFlushHandler::queue(const int type, const char* data) ...@@ -767,8 +776,9 @@ void CallbackFlushHandler::queue(const int type, const char* data)
{ {
RectangleAndPart rcNew = RectangleAndPart::Create(payload); RectangleAndPart rcNew = RectangleAndPart::Create(payload);
//SAL_WARN("lok", "New: " << rcNew.toString()); //SAL_WARN("lok", "New: " << rcNew.toString());
if (rcNew.m_aRectangle.IsEmpty()) if (rcNew.isInfinite())
{ {
SAL_WARN("lok", "Have Empty [" << type << "]: [" << payload << "] so removing all.");
removeAll( removeAll(
[type, &rcNew] (const queue_type::value_type& elem) { [type, &rcNew] (const queue_type::value_type& elem) {
if (elem.first == type) if (elem.first == type)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment